From: drowe67 Date: Thu, 7 Mar 2013 06:49:11 +0000 (+0000) Subject: both 1400 and 1600 modes working in loopback, needed to test 1400V0.91 against a... X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=ca67afbf69ff29536cdb8a9f9a013427df248476;p=freetel-svn-tracking.git both 1400 and 1600 modes working in loopback, needed to test 1400V0.91 against a V0.91 release git-svn-id: https://svn.code.sf.net/p/freetel/code@1194 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/fdmdv2/src/fdmdv2_defines.h b/fdmdv2/src/fdmdv2_defines.h index 42ce86e1..ded419b3 100644 --- a/fdmdv2/src/fdmdv2_defines.h +++ b/fdmdv2/src/fdmdv2_defines.h @@ -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__ diff --git a/fdmdv2/src/fdmdv2_main.cpp b/fdmdv2/src/fdmdv2_main.cpp index 1779d2b3..cba30486 100644 --- a/fdmdv2/src/fdmdv2_main.cpp +++ b/fdmdv2/src/fdmdv2_main.cpp @@ -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> 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); diff --git a/fdmdv2/src/fdmdv2_plot_scatter.cpp b/fdmdv2/src/fdmdv2_plot_scatter.cpp index 1c9707a6..a85e7320 100644 --- a/fdmdv2/src/fdmdv2_plot_scatter.cpp +++ b/fdmdv2/src/fdmdv2_plot_scatter.cpp @@ -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]; } diff --git a/fdmdv2/src/fdmdv2_plot_scatter.h b/fdmdv2/src/fdmdv2_plot_scatter.h index f33d3afe..bdcbe452 100644 --- a/fdmdv2/src/fdmdv2_plot_scatter.h +++ b/fdmdv2/src/fdmdv2_plot_scatter.h @@ -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; };