$ cd ~/codec2
$ rm -Rf build_linux && mkdir build_linux
- $ CFLAGS=-DDUMP cmake ..
$ cd build_linux
+ $ CFLAGS=-DDUMP cmake ..
$ make
Directories
subplot(212)
plot(20*log10(abs(fft(s4)/fs)))
grid
-title('After Flattening Filter');
+title('After Equaliser');
axis([0 fs/2/M -10 50])
--- /dev/null
+% 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)');
1;
+graphics_toolkit ("gnuplot");
+
function fm_states = analog_fm_init(fm_states)
% FM modulator constants
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;
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 staticc type noise at low SNRs
+ % limit maximum phase jumps, to remove static type noise at low SNRs
rx_out(find(rx_out > wd)) = wd;
rx_out(find(rx_out < -wd)) = -wd;
mod = sin(wm*t);
tx = analog_fm_mod(fm_states, mod);
-
+
% Channel ---------------------------------
noise = sqrt(variance/2)*(randn(1,nsam) + j*randn(1,nsam));
sim_in.pre_emp = 0;
sim_in.de_emp = 0;
- sim_in.CNdB = 25;
+ sim_in.CNdB = 20;
sim_out = analog_fm_test(sim_in);
end
+function fm_mod_file(file_name_out)
+ 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);
+
+ 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")';
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
+
+
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");
k++;
end
+ figure
+ subplot(211)
+ stem(re_syms)
+ subplot(211)
+ stem(im_syms)
+
figure;
clf
subplot(211)
Rs = 1200;
framesize = 480;
npreamble = 480;
- fc = 1500;
+ fc = 1900;
gmsk_states.npreamble = npreamble;
gmsk_states.verbose = 1;
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);
rx_power_dB = 10*log10(rx_power);
figure;
subplot(211)
- plot(rx_filt);
+ plot(rx_filt(1000:5*Fs));
title('GMSK Power (narrow filter)');
subplot(212)
plot(rx_power_dB);
- axis([1 length(rx_power) max(rx_power_dB)-9 max(rx_power_dB)+1])
+ 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
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 + 22*framesize*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;
%run_test_channel_impairments
%gmsk_tx("test_gmsk.raw")
%gmsk_rx("ssb-ber5.wav")
-gmsk_rx("~/Desktop/ssb25db.wav")
+%gmsk_rx("ssb25db.wav")
%gmsk_rx("~/Desktop/ssb_fm_gmsk_high.wav")
+gmsk_rx("~/Desktop/test_gmsk_28BER.raw")
codec2.c
fifo.c
fdmdv.c
+ fm.c
kiss_fft.c
interp.c
lsp.c
golay23.h
codec2.h
codec2_fdmdv.h
+ codec2_fm.h
codec2_fifo.h
comp.h
)
add_executable(freedv_rx freedv_rx.c)
target_link_libraries(freedv_rx ${CMAKE_REQUIRED_LIBRARIES} codec2)
+add_executable(fm_demod fm_demod.c fm.c)
+target_link_libraries(fm_demod ${CMAKE_REQUIRED_LIBRARIES})
+
install(TARGETS codec2 EXPORT codec2-config
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
c2sim
fdmdv_get_test_bits
fdmdv_mod fdmdv_demod
+ fm_demod
fdmdv_put_test_bits
fdmdv_interleave
insert_errors
//printf("Wo %f e %f\n", model.Wo, e);
}
-
+
aks_to_M2(fft_fwd_cfg, ak, order, &model, e, &snr, 1, simlpcpf, lpcpf, 1, LPCPF_BETA, LPCPF_GAMMA, Aw);
apply_lpc_correction(&model);
--- /dev/null
+/*---------------------------------------------------------------------------*\
+
+ 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;
+ 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[]);
+
+#endif
+
--- /dev/null
+/*---------------------------------------------------------------------------*\
+
+ 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"
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTIONS
+
+\*---------------------------------------------------------------------------*/
+
+static COMP cconj(COMP a)
+{
+ COMP res;
+
+ res.real = a.real;
+ res.imag = -a.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 COMP fcmult(float a, COMP b)
+{
+ COMP res;
+
+ res.real = a*b.real;
+ res.imag = a*b.imag;
+
+ return res;
+}
+
+static float cabsolute(COMP a)
+{
+ return sqrtf(powf(a.real, 2.0) + powf(a.imag, 2.0));
+}
+
+/*---------------------------------------------------------------------------*\
+
+ 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->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, 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 = cos(wc); wc_rect.imag = -sin(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; k++) {
+ rx_bb_filt.real += rx_bb[i-k].real * bin[k];
+ rx_bb_filt.imag += rx_bb[i-k].imag * bin[k];
+ }
+ //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 = atan2(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] = acc;
+ }
+
+ /* 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;
+
+}
--- /dev/null
+/*---------------------------------------------------------------------------*\
+
+ 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
+
+int main(int argc, char *argv[])
+{
+ FILE *fin, *fout;
+ struct FM *fm;
+ short buf[N];
+ float rx[N];
+ float rx_out[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 = 44400.0;
+ fm->fm_max = 3000.0;
+ fm->fd = 5000.0;
+ fm->fc = fm->Fs/4;
+
+ while(fread(buf, sizeof(short), N, fin) == N) {
+ for(i=0; i<N; i++) {
+ rx[i] = buf[i];
+ }
+ fm_demod(fm, rx_out, rx);
+ for(i=0; i<N; i++) {
+ buf[i] = 16384*rx_out[i];
+ }
+ fwrite(buf, sizeof(short), N, fout);
+ }
+
+ fm_destroy(fm);
+ fclose(fin);
+ fclose(fout);
+
+ return 0;
+}
--- /dev/null
+/* 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
+};