system("../fm_test fm_test_sig.raw fm_test_out.raw");
ftmod = fopen("fm_test_out.raw","r");
- test_mod = fread(ftmod,"short")/16384;
+ 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);
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);
+ mod_diff = test_mod .- comp_mod;
+ plot(real(mod_diff),test_t,imag(mod_diff),test_t);
endfunction
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
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
+ 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_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;
+}
#define N 160
-#define TEST_MOD
+#define TEST_MOD_COMP
int main(int argc, char *argv[])
{
FILE *fin, *fout;
struct FM *fm;
- short buf[N];
+ short buf[N*2];
float rx[N];
float rx_out[N];
+ COMP out_comp[N];
int i;
if (argc < 2) {
}
#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);