both 1400 and 1600 modes working in loopback, needed to test 1400V0.91 against a...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 7 Mar 2013 06:49:11 +0000 (06:49 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Thu, 7 Mar 2013 06:49:11 +0000 (06:49 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1194 01035d8c-6547-0410-b346-abe4f91aad63

fdmdv2/src/fdmdv2_defines.h
fdmdv2/src/fdmdv2_main.cpp
fdmdv2/src/fdmdv2_plot_scatter.cpp
fdmdv2/src/fdmdv2_plot_scatter.h

index 42ce86e194684a28bbfc502bbae3982ef8e4ef29..ded419b32c3c08bcf4856672dfee0e3f4ee49945 100644 (file)
@@ -44,7 +44,7 @@
 #define SCATTER_MEM_SECS    2
 // (symbols/frame)/(graphics update period) = symbols/s sent to scatter memory
 // memory (symbols) = secs of memory * symbols/sec
-#define SCATTER_MEM_SYMS    ((int)(SCATTER_MEM_SECS*(FDMDV_NSYM/DT)))
+#define SCATTER_MEM_SYMS_MAX    ((int)(SCATTER_MEM_SECS*((FDMDV_NC_MAX+1)/DT)))
 
 // Waveform plotting constants
 
@@ -62,8 +62,9 @@
 #define N48                 (N8*FDMDV_OS)                  // processing buffer size at 48 kHz
 #define NUM_CHANNELS        2                              // I think most sound cards prefer stereo we will convert to mono
 
-#define BITS_PER_CODEC_FRAME  (2 * FDMDV_BITS_PER_FRAME)
-#define BYTES_PER_CODEC_FRAME (BITS_PER_CODEC_FRAME / 8)
+#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      4.0
@@ -92,4 +93,11 @@ enum
 #define CODEC2_LPC_PF_GAMMA 0.5
 #define CODEC2_LPC_PF_BETA  0.2
 
+// FreeDV modes
+
+#define MODE_1400_V0_91  0   // Legacy 1400 from Dec 2012 V0.91 release with incorrect QPSK mapping
+#define MODE_1400        1   // 1400 bit/s codec, no FEC
+#define MODE_1600        2   // 1600 bit/s codec, no FEC
+#define MODE_2000        3   // 1400 bit/s codec, 600 bit/s FEC on most sensitive bits, 2000 bit/s total
+
 #endif  //__FDMDV2_DEFINES__
index 1779d2b32b0f4280fd6f75a2441f41ba5120d8f7..cba30486d0a5b83578995f69742a90d22c708501 100644 (file)
@@ -34,6 +34,7 @@
 // ------------------------------------------------------------------
 
 // Global Codec2 & modem states - just one reqd for tx & rx
+int                 g_mode;
 struct CODEC2      *g_pCodec2;
 struct FDMDV       *g_pFDMDV;
 struct FDMDV_STATS  g_stats;
@@ -57,7 +58,7 @@ struct FIFO         *g_rxDataOutFifo;
 
 // tx/rx processing states
 int                 g_nRxIn = FDMDV_NOM_SAMPLES_PER_FRAME;
-int                 g_CodecBits[2 * FDMDV_BITS_PER_FRAME];
+int                 g_CodecBits[MAX_BITS_PER_CODEC_FRAME];
 int                 g_State;
 paCallBackData     *g_rxUserdata;
 
@@ -1481,6 +1482,8 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
         // Start Running -------------------------------------------------
         //
 
+        // modify some button states when running
+
         m_togBtnSplit->Enable();
         //m_togRxID->Enable();
         //m_togTxID->Enable();
@@ -1493,10 +1496,47 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
 */
         m_togBtnOnOff->SetLabel(wxT("Stop"));
 
+        m_rb1400old->Disable();
+        m_rb1400->Disable();
+        m_rb1600->Disable();
+        m_rb2000->Disable();
+
+        // determine what mode we are using
+
+        int Nc, codec2_mode;
+        if (m_rb1400old->GetValue()) {
+            g_mode = MODE_1400_V0_91;
+            Nc = 14;
+            codec2_mode = CODEC2_MODE_1400;
+        }
+        if (m_rb1400->GetValue()) {
+            g_mode = MODE_1400;
+            Nc = 14;
+            codec2_mode = CODEC2_MODE_1400;
+        }
+        if (m_rb1600->GetValue()) {
+            g_mode = MODE_1600;
+            Nc = 16;
+            codec2_mode = CODEC2_MODE_1600;
+        }
+        if (m_rb2000->GetValue()) {
+            g_mode = MODE_2000;
+            Nc = 20;
+            codec2_mode = CODEC2_MODE_1400;
+        }
+        printf("g_mode: %d  Nc: %d  codec2_mode: %d\n", g_mode, Nc, codec2_mode);
+
         // init modem and codec states
 
-        g_pFDMDV  = fdmdv_create();
-        g_pCodec2 = codec2_create(CODEC2_MODE_1400);
+        g_pFDMDV  = fdmdv_create(Nc);
+        g_pCodec2 = codec2_create(codec2_mode);
+
+        if (g_mode == MODE_1400_V0_91)
+            fdmdv_use_old_qpsk_mapping(g_pFDMDV);
+
+        // adjust scatter diagram for Number of FDM carriers
+
+        m_panelScatter->setNc(Nc);
 
         // init Codec 2 LPC Post Filter
 
@@ -1554,6 +1594,10 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
         m_togBtnAnalog->Disable();
         //m_btnTogPTT->Disable();
         m_togBtnOnOff->SetLabel(wxT("Start"));
+        m_rb1400old->Enable();
+        m_rb1400->Enable();
+        m_rb1600->Enable();
+        m_rb2000->Enable();
     }
 }
 
@@ -2305,14 +2349,24 @@ void per_frame_rx_processing(
     short               output_buf[N8*2];
     COMP                rx_fdm[FDMDV_MAX_SAMPLES_PER_FRAME];
     COMP                rx_fdm_offset[FDMDV_MAX_SAMPLES_PER_FRAME];
-    int                 rx_bits[FDMDV_BITS_PER_FRAME];
-    unsigned char       packed_bits[BYTES_PER_CODEC_FRAME];
+    int                 rx_bits[MAX_BITS_PER_FDMDV_FRAME];
+    unsigned char       packed_bits[MAX_BYTES_PER_CODEC_FRAME];
     float               rx_spec[FDMDV_NSPEC];
     int                 i;
     int                 nin_prev;
     int                 bit;
     int                 byte;
     int                 next_state;
+    int                 bits_per_fdmdv_frame, bits_per_codec_frame, bytes_per_codec_frame;
+
+    bits_per_fdmdv_frame = fdmdv_bits_per_frame(g_pFDMDV);
+    printf(" bits_per_fdmdv_frame: %d\n", bits_per_fdmdv_frame);
+    assert(bits_per_fdmdv_frame <= MAX_BITS_PER_FDMDV_FRAME);
+    bits_per_codec_frame = codec2_bits_per_frame(c2);
+    assert(bits_per_codec_frame <= MAX_BITS_PER_CODEC_FRAME);
+    assert((bits_per_codec_frame % 8) == 0);
+    bytes_per_codec_frame = bits_per_codec_frame/8;
+    assert(bytes_per_codec_frame <= MAX_BYTES_PER_CODEC_FRAME);
 
     //
     //  This while loop will run the demod 0, 1 (nominal) or 2 times:
@@ -2380,7 +2434,7 @@ void per_frame_rx_processing(
                 {
                     next_state = 1;
                 }
-        //printf("sync state: %d\n", *state);
+                //printf("sync state: %d\n", *state);
                 break;
 
             case 1:
@@ -2388,7 +2442,7 @@ void per_frame_rx_processing(
                 {
                     next_state = 2;
                     // first half of frame of codec bits
-                    memcpy(codec_bits, rx_bits, FDMDV_BITS_PER_FRAME * sizeof(int));
+                    memcpy(codec_bits, rx_bits, bits_per_fdmdv_frame * sizeof(int));
                 }
                 else
                 {
@@ -2408,14 +2462,15 @@ void per_frame_rx_processing(
                 }
                 if(sync_bit == 1)
                 {
-                    int  data_flag_index;
+                    int  data_flag_index, valid;
 
                     // second half of frame of codec bits
-                    memcpy(&codec_bits[FDMDV_BITS_PER_FRAME], rx_bits, FDMDV_BITS_PER_FRAME*sizeof(int));
+                    memcpy(&codec_bits[bits_per_fdmdv_frame], rx_bits, bits_per_fdmdv_frame *sizeof(int));
 
                     // extract data bit
 
                     data_flag_index = codec2_get_spare_bit_index(c2);
+                    printf("data_flag_index: %d\n", data_flag_index);
                     assert(data_flag_index != -1); // not supported for all rates
                     
                     short abit = codec_bits[data_flag_index];
@@ -2430,14 +2485,15 @@ void per_frame_rx_processing(
 
                     // reconstruct missing bit we steal for data bit and decode speech
                         
-                    codec2_rebuild_spare_bit(c2, codec_bits);
+                    valid = codec2_rebuild_spare_bit(c2, codec_bits);
+                    assert(valid != -1);
 
                     // 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++)
+                    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--;
@@ -2447,7 +2503,7 @@ void per_frame_rx_processing(
                             byte++;
                         }
                     }
-                    assert(byte == BYTES_PER_CODEC_FRAME);
+                    assert(byte ==  bytes_per_codec_frame);
 
                     // add decoded speech to end of output buffer
 
@@ -2468,20 +2524,29 @@ void per_frame_tx_processing(
                                             CODEC2  *c2             // Codec 2 states
                                         )
 {
-    unsigned char  packed_bits[BYTES_PER_CODEC_FRAME];
-    int            bits[BITS_PER_CODEC_FRAME];
+    unsigned char  packed_bits[MAX_BYTES_PER_CODEC_FRAME];
+    int            bits[MAX_BITS_PER_CODEC_FRAME];
     COMP           tx_fdm[2*FDMDV_NOM_SAMPLES_PER_FRAME];
     COMP           tx_fdm_offset[2*FDMDV_NOM_SAMPLES_PER_FRAME];
     int            sync_bit;
     int            i, bit, byte, data_flag_index;
     short          abit;
+    int            bits_per_fdmdv_frame, bits_per_codec_frame, bytes_per_codec_frame;
+
+    bits_per_fdmdv_frame = fdmdv_bits_per_frame(g_pFDMDV);
+    assert(bits_per_fdmdv_frame <= MAX_BITS_PER_FDMDV_FRAME);
+    bits_per_codec_frame = codec2_bits_per_frame(c2);
+    assert(bits_per_codec_frame <= MAX_BITS_PER_CODEC_FRAME);
+    assert((bits_per_codec_frame % 8) == 0);
+    bytes_per_codec_frame = bits_per_codec_frame/8;
+    assert(bytes_per_codec_frame <= MAX_BYTES_PER_CODEC_FRAME);
 
     codec2_encode(c2, packed_bits, input_buf);
 
     /* unpack bits, MSB first */
 
     bit = 7; byte = 0;
-    for(i=0; i<BITS_PER_CODEC_FRAME; i++) {
+    for(i=0; i<bits_per_codec_frame; i++) {
         bits[i] = (packed_bits[byte] >> bit) & 0x1;
         bit--;
         if (bit < 0) {
@@ -2489,7 +2554,7 @@ void per_frame_tx_processing(
             byte++;
         }
     }
-    assert(byte == BYTES_PER_CODEC_FRAME);
+    assert(byte == bytes_per_codec_frame);
 
     // voice/data flag is a spare bit in 1400 bit/s frame that
     // codec defines.  Use this 1 bit/frame to send call sign data
@@ -2507,7 +2572,7 @@ void per_frame_tx_processing(
     fdmdv_mod(g_pFDMDV, tx_fdm, bits, &sync_bit);
     assert(sync_bit == 1);
 
-    fdmdv_mod(g_pFDMDV, &tx_fdm[FDMDV_NOM_SAMPLES_PER_FRAME], &bits[FDMDV_BITS_PER_FRAME], &sync_bit);
+    fdmdv_mod(g_pFDMDV, &tx_fdm[FDMDV_NOM_SAMPLES_PER_FRAME], &bits[bits_per_fdmdv_frame], &sync_bit);
     assert(sync_bit == 0);
 
     fdmdv_freq_shift(tx_fdm_offset, tx_fdm, g_TxFreqOffsetHz, &g_TxFreqOffsetPhaseRect, &g_TxFreqOffsetFreqRect, 2*FDMDV_NOM_SAMPLES_PER_FRAME);
index 1c9707a69c530cad7587cbcde7a014dfa0697591..a85e73202c7175d2509202797ae56e29ed126000 100644 (file)
@@ -38,13 +38,28 @@ PlotScatter::PlotScatter(wxFrame* parent) : PlotPanel(parent)
 {
     int i;
 
-    for(i=0; i < SCATTER_MEM_SYMS; 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 = 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);
+        
+}
+
+// changing number of carriers changes number of symoles to plot
+void PlotScatter::setNc(int Nc) {
+    Nsym = Nc+1;
+    assert(Nsym <= (FDMDV_NC_MAX+1));
+    scatterMemSyms = ((int)(SCATTER_MEM_SECS*(Nsym/DT)));
+    assert(scatterMemSyms <= SCATTER_MEM_SYMS_MAX);
 }
 
 //----------------------------------------------------------------
@@ -78,14 +93,14 @@ void PlotScatter::draw(wxAutoBufferedPaintDC& dc)
 
     // shift memory
 
-    for(i = 0; i < SCATTER_MEM_SYMS-FDMDV_NSYM; i++)
+    for(i = 0; i < scatterMemSyms - Nsym; i++)
     {
-        m_mem[i] = m_mem[i+FDMDV_NSYM];
+        m_mem[i] = m_mem[i+Nsym];
     }
 
     // new samples
 
-    for(j=0; i < SCATTER_MEM_SYMS; i++,j++)
+    for(j=0; i < scatterMemSyms; i++,j++)
     {
         m_mem[i] = m_new_samples[j];
     }
@@ -94,7 +109,7 @@ void PlotScatter::draw(wxAutoBufferedPaintDC& dc)
 
     float max_xy = 1E-12;
     float real,imag;
-    for(i=0; i< SCATTER_MEM_SYMS; i++) {
+    for(i=0; i< scatterMemSyms; i++) {
         real = fabs(m_mem[i].real);
         imag = fabs(m_mem[i].imag);
         if (real > max_xy)
@@ -112,7 +127,7 @@ void PlotScatter::draw(wxAutoBufferedPaintDC& dc)
 
     // draw all samples
 
-    for(i = 0; i < SCATTER_MEM_SYMS; i++)
+    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;
@@ -129,7 +144,7 @@ void PlotScatter::add_new_samples(COMP samples[])
 {
     int i;
 
-    for(i = 0; i < FDMDV_NSYM; i++)
+    for(i = 0; i < Nsym; i++)
     {
         m_new_samples[i] = samples[i];
     }
index f33d3afef7c82adc99057d1e5232e4dfea82208d..bdcbe452ec31236e3bbe8355011c00b90226fc0d 100644 (file)
@@ -34,10 +34,11 @@ class PlotScatter : public PlotPanel
         PlotScatter(wxFrame* parent);
         ~PlotScatter(){};
        void add_new_samples(COMP samples[]);
+       void setNc(int Nc);
 
     protected:
-        COMP m_mem[SCATTER_MEM_SYMS];
-        COMP m_new_samples[FDMDV_NSYM];
+        COMP m_mem[SCATTER_MEM_SYMS_MAX];
+        COMP m_new_samples[FDMDV_NC_MAX+1];
 
         void draw(wxAutoBufferedPaintDC&  dc);
         void OnPaint(wxPaintEvent& event);
@@ -47,6 +48,8 @@ class PlotScatter : public PlotPanel
         DECLARE_EVENT_TABLE()
 
     private:
+        int   Nsym;
+        int   scatterMemSyms;
         float m_filter_max_xy;
 };