Hi All,

On 07/15/2018 01:25 AM, David Rowe wrote:
> Hello Jeroen,
>
> 1/ So does your system actually use FreeDV 2400B?  What does freedv_eth do?
freedv_eth is my frontend for connecting to the radio.
It can control the radio with hamlib, and used alsa for sound input and
output.
It creates an software ethernet device for communication with other
programs (such as the DML ones)
It can receive and transmit both freedv (in theory any of the modes) and
analog audio, even in mixed mode.
The audio data is transmitted/received on the ethernet device.
As well as any data packets. For example received when using mode 2400B,
but also any varicode received or decoded dtmf.
It can also generate morse beacons, and in case of a fullduplex set it
can loop received audio back to the transmitter for use as a repeater.

The advantage is that my DML code does not have to do anything with the
radio, it can just communicate using a raw socket on the network device.

>
> 2/ If possible, it would be much appreciated if you extend your work on
> freedv_codecrx() and freedv_codectx() to 700D.
See the attached patch.
It contains a modified codecrx and codectx. (They can be verified by
running freedv_tx and freedv_rx with and without the codectx and codecrx
options and comparing the output)
It also contains get_energy functions for the new codec2 450 modes.
And it modifies the get_stats function to return the freedv sync state
such that it can actually be used as a squelch (also for 2400B)
And lastly a fix for a small initialization problem I had with the
datachannel code.

Regards,
Jeroen

diff -ruN codec2-dev-r3751/src/codec2.c codec2-dev-r3751-pe1rxq/src/codec2.c
--- codec2-dev-r3751/src/codec2.c	2018-07-11 03:15:36.000000000 +0200
+++ codec2-dev-r3751-pe1rxq/src/codec2.c	2018-07-18 15:05:37.368333621 +0200
@@ -2008,6 +2008,27 @@
     return powf(10.0, mean/10.0);
 }
 
+float codec2_energy_450(struct CODEC2 *c2, const unsigned char * bits)
+{
+    int     indexes[4];
+    unsigned int nbit = 0;
+
+    assert(c2 != NULL);
+
+    /* unpack bits from channel ------------------------------------*/
+
+    indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0);
+    //indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0);
+    indexes[2] = unpack_natural_or_gray(bits, &nbit, 3, 0);
+    indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0);
+    
+    float mean = newamp2_energy_cb[0].cb[indexes[2]];
+    mean -= 10;
+    if (indexes[3] == 0)
+    	mean -= 10;
+
+    return powf(10.0, mean/10.0);
+}
 
 /*---------------------------------------------------------------------------*\
 
@@ -2031,7 +2052,9 @@
 	   (c2->mode == CODEC2_MODE_1200) ||
 	   (c2->mode == CODEC2_MODE_700) ||
 	   (c2->mode == CODEC2_MODE_700B) ||
-	   (c2->mode == CODEC2_MODE_700C)
+	   (c2->mode == CODEC2_MODE_700C) ||
+	   (c2->mode == CODEC2_MODE_450) ||
+	   (c2->mode == CODEC2_MODE_450PWB)
 	   );
     MODEL model;
     float xq_dec[2] = {};
@@ -2082,6 +2105,9 @@
     if (c2->mode == CODEC2_MODE_700C) {
         e = codec2_energy_700c(c2, bits);
     }
+    if (c2->mode == CODEC2_MODE_450 || c2->mode == CODEC2_MODE_450PWB) {
+        e = codec2_energy_450(c2, bits);
+    }
     
     return e;
 }
diff -ruN codec2-dev-r3751/src/freedv_api.c codec2-dev-r3751-pe1rxq/src/freedv_api.c
--- codec2-dev-r3751/src/freedv_api.c	2018-06-14 02:43:04.000000000 +0200
+++ codec2-dev-r3751-pe1rxq/src/freedv_api.c	2018-07-19 00:20:11.545080682 +0200
@@ -1090,6 +1090,35 @@
         case FREEDV_MODE_700C:
             freedv_comptx_700(f, tx_fdm);
             break;
+        case FREEDV_MODE_700D: {
+            /* special treatment due to interleaver */
+            int data_bits_per_frame = f->ldpc->data_bits_per_frame;
+	    int codec_frames = data_bits_per_frame / bits_per_codec_frame;
+	    int j;
+
+            /* buffer up bits until we get enough encoded bits for interleaver */
+        
+            for (j=0; j<codec_frames; j++) {
+                memcpy(f->packed_codec_bits_tx + (f->modem_frame_count_tx*codec_frames+j)*bytes_per_codec_frame, packed_codec_bits, bytes_per_codec_frame);
+	        packed_codec_bits += bytes_per_codec_frame;
+            }
+
+            /* call modulate function when we have enough frames to run interleaver */
+
+            assert((f->modem_frame_count_tx >= 0) && (f->modem_frame_count_tx < f->interleave_frames));
+            f->modem_frame_count_tx++;
+            if (f->modem_frame_count_tx == f->interleave_frames) {
+                freedv_comptx_700d(f, f->mod_out);
+                f->modem_frame_count_tx = 0;
+            }
+
+            /* output n_nom_modem_samples at a time from modulated buffer */
+            for(i=0; i<f->n_nat_modem_samples; i++) {
+                mod_out[i] = f->mod_out[f->modem_frame_count_tx*f->n_nat_modem_samples+i].real;
+            }
+
+	    return; /* output is already real */
+	}
         case FREEDV_MODE_2400A:
         case FREEDV_MODE_2400B:
         case FREEDV_MODE_800XA:
@@ -1949,6 +1978,8 @@
     int nin = freedv_nin(f);
     int valid;
     int ret = 0;
+    int bits_per_codec_frame = codec2_bits_per_frame(f->codec2);
+    int bytes_per_codec_frame = (bits_per_codec_frame + 7) / 8;
 
     assert(nin <= f->n_max_modem_samples);
     
@@ -1965,6 +1996,23 @@
     if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_700C)) {
         freedv_comprx_700(f, rx_fdm, &valid);
     }
+
+    if (f->mode == FREEDV_MODE_700D) {
+        freedv_comprx_700d(f, rx_fdm, &valid);
+
+        int data_bits_per_frame = f->ldpc->data_bits_per_frame;
+        int frames = data_bits_per_frame/bits_per_codec_frame;
+            
+        if (valid == 1 && f->modem_frame_count_rx < f->interleave_frames) {
+             for (i = 0; i < frames; i++) {
+                 memcpy(packed_codec_bits, f->packed_codec_bits + (i + frames*f->modem_frame_count_rx)* bytes_per_codec_frame, bytes_per_codec_frame);
+                 packed_codec_bits += bytes_per_codec_frame;
+                 ret += bytes_per_codec_frame;
+             }
+             f->modem_frame_count_rx++;
+        }
+	return ret;
+    }
 #endif
     
     if( (f->mode == FREEDV_MODE_2400A) || (f->mode == FREEDV_MODE_2400B) || (f->mode == FREEDV_MODE_800XA)){
@@ -1972,7 +2020,6 @@
     }
 
     if (valid == 1) {
-        int bits_per_codec_frame = codec2_bits_per_frame(f->codec2);
         int bytes_per_codec_frame = (bits_per_codec_frame + 7) / 8;
         int codec_frames = f->n_codec_bits / bits_per_codec_frame;
 
@@ -2119,8 +2166,11 @@
     if (f->mode == FREEDV_MODE_700D) {
         ofdm_get_demod_stats(f->ofdm, &f->stats);
     }
+    if (f->mode == FREEDV_MODE_2400B) {
+        fmfsk_get_demod_stats(f->fmfsk, &f->stats);
+    }
 #endif
-    if (sync) *sync = f->stats.sync;
+    if (sync) *sync = f->sync;
     if (snr_est) *snr_est = f->stats.snr_est;
 }
 
diff -ruN codec2-dev-r3751/src/freedv_data_channel.c codec2-dev-r3751-pe1rxq/src/freedv_data_channel.c
--- codec2-dev-r3751/src/freedv_data_channel.c	2016-05-10 02:49:58.000000000 +0200
+++ codec2-dev-r3751-pe1rxq/src/freedv_data_channel.c	2018-07-19 00:11:32.921598384 +0200
@@ -113,6 +113,8 @@
         return NULL;
 
     fdc->cb_rx = NULL;
+    fdc->cb_tx = NULL;
+    fdc->packet_tx_size = 0;
 
     freedv_data_set_header(fdc, fdc_header_bcast);
 
diff -ruN codec2-dev-r3751/src/freedv_rx.c codec2-dev-r3751-pe1rxq/src/freedv_rx.c
--- codec2-dev-r3751/src/freedv_rx.c	2018-05-08 10:46:02.000000000 +0200
+++ codec2-dev-r3751-pe1rxq/src/freedv_rx.c	2018-07-18 15:15:24.479331289 +0200
@@ -152,6 +152,8 @@
 		    c2_mode = CODEC2_MODE_700;
 		} else if ((mode == FREEDV_MODE_700B)|| (mode == FREEDV_MODE_800XA)) {
                     c2_mode = CODEC2_MODE_700B;
+                } else if ((mode == FREEDV_MODE_700C)|| (mode == FREEDV_MODE_700D)) {
+                    c2_mode = CODEC2_MODE_700C;
                 } else {
                     c2_mode = CODEC2_MODE_1300;
                 }
@@ -232,6 +234,7 @@
                 }
             }
         }
+fprintf(stderr, "nout: %d\n", nout);
 
         nin = freedv_nin(freedv);
 
diff -ruN codec2-dev-r3751/src/freedv_tx.c codec2-dev-r3751-pe1rxq/src/freedv_tx.c
--- codec2-dev-r3751/src/freedv_tx.c	2018-07-13 21:53:54.000000000 +0200
+++ codec2-dev-r3751-pe1rxq/src/freedv_tx.c	2018-07-18 14:11:36.575054370 +0200
@@ -156,6 +156,8 @@
                     c2_mode = CODEC2_MODE_700;
                 } else if ((mode == FREEDV_MODE_700B)|| (mode == FREEDV_MODE_800XA)) {
                     c2_mode = CODEC2_MODE_700B;
+                } else if ((mode == FREEDV_MODE_700C)|| (mode == FREEDV_MODE_700D)) {
+                    c2_mode = CODEC2_MODE_700C;
                 } else {
                     c2_mode = CODEC2_MODE_1300;
                 }
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Freetel-codec2 mailing list
Freetel-codec2@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freetel-codec2

Reply via email to