complex domain FM modulator written and tested
authorbaobrien <baobrien@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 11 Sep 2015 03:24:21 +0000 (03:24 +0000)
committerbaobrien <baobrien@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 11 Sep 2015 03:24:21 +0000 (03:24 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@2304 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/fm.m
codec2-dev/src/codec2_fm.h
codec2-dev/src/fm.c
codec2-dev/src/fm_demod.c

index 99c68025aaf83807bc21e7dc65f6bbe5d8cd6711..50c4099f8632f2efe9e5d7805be615050dde14e1 100644 (file)
@@ -438,7 +438,10 @@ function test_fm_modulator
   
   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);
@@ -448,8 +451,8 @@ function test_fm_modulator
   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
 
index 630ac23fa29d433e1b8d6593d677c5550da22da3..8b79ae4a249d1fb5ce6c004d8604872825cd196e 100644 (file)
@@ -47,6 +47,7 @@ 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
 
index d63e0999ad5dc9259af111b5efaf2b3cd7ac1987..37e7a97aa5d612d6934f94a9758a60437e0298fc 100644 (file)
@@ -240,18 +240,48 @@ void fm_mod(struct FM *fm_states, float tx_in[], float tx_out[]){
   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;
+}
 
index fd4301bd52110ff07ccc24c02c220ce0a8fe0349..58a322a066ae7558beb0ac394dd099ec1c84bf3d 100644 (file)
 
 #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) {
@@ -81,13 +82,27 @@ int main(int argc, char *argv[])
         }
 #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);