From: baobrien Date: Fri, 11 Sep 2015 02:34:37 +0000 (+0000) Subject: Added and tested real->real FM modulator X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=f45d5a32d265e70e8e972eb8296d9e05b725d853;p=freetel-svn-tracking.git Added and tested real->real FM modulator git-svn-id: https://svn.code.sf.net/p/freetel/code@2303 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/octave/fm.m b/codec2-dev/octave/fm.m index 765aae12..99c68025 100644 --- a/codec2-dev/octave/fm.m +++ b/codec2-dev/octave/fm.m @@ -291,7 +291,7 @@ end function fm_mod_file(file_name_out) - fm_states.Fs = 44400; + fm_states.Fs = 48000; fm_states.fm_max = 3E3; fm_states.fd = 5E3; fm_states.fc = fm_states.Fs/4; @@ -412,6 +412,46 @@ function make_coeff_file 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.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 = fread(ftmod,"short")/16384; + 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 = rot90(test_mod) .- comp_mod_real; + plot(mod_diff); + +endfunction more off; @@ -420,4 +460,5 @@ more off; %fm_demod_file("ssb25_fm_de.raw", "~/Desktop/ssb25db.wav") %run_fm_single %make_coeff_file -fm_mod_file("fm_1000.raw"); +%fm_mod_file("fm_1000.raw"); +test_fm_modulator diff --git a/codec2-dev/src/codec2_fm.h b/codec2-dev/src/codec2_fm.h index 92457ecf..630ac23f 100644 --- a/codec2-dev/src/codec2_fm.h +++ b/codec2-dev/src/codec2_fm.h @@ -37,7 +37,8 @@ struct FM { float fc; /* setme: carrier frequency */ COMP *rx_bb; COMP rx_bb_filt_prev; - float *rx_dem_mem; + float *rx_dem_mem; + float tx_phase; int nsam; COMP lo_phase; }; @@ -45,6 +46,7 @@ struct FM { 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[]); #endif diff --git a/codec2-dev/src/fm.c b/codec2-dev/src/fm.c index bdccd8a8..d63e0999 100644 --- a/codec2-dev/src/fm.c +++ b/codec2-dev/src/fm.c @@ -83,6 +83,8 @@ struct FM *fm_create(int nsam) 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); @@ -193,3 +195,63 @@ void fm_demod(struct FM *fm_states, float rx_out[], float rx[]) 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 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; +} + + + + + + + + + + + + + + + + diff --git a/codec2-dev/src/fm_demod.c b/codec2-dev/src/fm_demod.c index 8042df65..fd4301bd 100644 --- a/codec2-dev/src/fm_demod.c +++ b/codec2-dev/src/fm_demod.c @@ -38,6 +38,8 @@ #define N 160 +#define TEST_MOD + int main(int argc, char *argv[]) { FILE *fin, *fout; @@ -68,16 +70,20 @@ int main(int argc, char *argv[]) } fm = fm_create(N); - fm->Fs = 44400.0; + fm->Fs = 48000.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