analog 6dB boost on mic, some experiments with waterfall blue colors, using 200-2800H...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 7 Dec 2012 00:14:53 +0000 (00:14 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Fri, 7 Dec 2012 00:14:53 +0000 (00:14 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1124 01035d8c-6547-0410-b346-abe4f91aad63

fdmdv2/README.linux
fdmdv2/src/Makefile.linux
fdmdv2/src/fdmdv2_main.cpp
fdmdv2/src/fdmdv2_plot_waterfall_linux.cpp

index 90a6fa6624bdd8ae2bf6a162a3df0f56de1afa73..58c3996715f5c6241b6193e9d64610b3797c150e 100644 (file)
@@ -5,14 +5,34 @@ Oct 14 2012
 Linux usage Notes
 =================
 
-1. Config is stored in ~/.FMDV2, rm this file to restore defaults
+1. Config is stored in ~/.FreeDV, rm this file to restore defaults
 
 
-BUILDING fdmdv2 for Linux
+BUILDING FreeDV for Linux
 =========================
 
-Build wxWidgets
----------------
+1  FreeDV was developed on Ubuntu 9.1 and 10.04 systems.  I installed the
+   Ubuntu packages:
+
+     libsamplerate, libsamplerate-dev
+     libsndfile1, libsndfile1-dev
+
+2. Some people have also reported needing libasound (and -lasound in
+   the linker line of Makefile.linux)
+
+3. Then build the other libraries below from source. At present the
+   way each package is built and installed is not consistent.  Some
+   are installed with "make install", others are pointed too via
+   Makefile variables.  
+
+4. You may need to edit the Makefile.linux variables for your system:
+
+   WX_GTK_PATH
+   CODEC2_PATH
+   SOX_LIB_PATH
+
+wxWidgets
+---------
 
 1. Download wxWidgets 2.9.4 or later and untar
 
@@ -30,8 +50,8 @@ Build wxWidgets
    really want to), it can be used by fdmdv2 out of the directory you
    build it in.
 
-Build portaudio
----------------
+Portaudio
+---------
 
 1. Make sure ALSA development support (libasound and headers) is
    present.  Portaudio will work with OSS but I found I couldn't
@@ -41,7 +61,7 @@ Build portaudio
      sudo apt-get install libasound-dev
 
    Note I had problems with the ALSA development library on Ubuntu
-   9.10, so used OSS andput up with not being able to adjust the mic
+   9.10, so used OSS and put up with not being able to adjust the mic
    gain.
 
 2. Download and untar pa_stable_V19
@@ -73,9 +93,8 @@ Build portaudio
    possible to build fdmdv2 without "make install", by passing
    --prefix to the ./configure stage.
 
-<<<<<<< .mine
-Build libsox
-------------
+libsox
+------
 
 We use some of the internal sox functions for the equaliser feature.
 
@@ -90,9 +109,8 @@ sox-14.4.0$ ./configure --enable-shared=no --without-id3tag --without-png --disa
 
 sox-14.4.0$ make
 
-=======
-Build libctb (Communications Toolbox)
--------------------------------------
+libctb (Communications Toolbox)
+-------------------------------
 
 $ wget https://iftools.com/download/ctb/0.16/libctb-0.16.tar.gz
 $ tar xvzf libctb-0.16.tar.gz
@@ -105,14 +123,13 @@ I found the "sudo make DEBUG=0 GPIB=0 install" didn't install the kbhit.h file:
 build$ sudo cp ../include/ctb-0.16/kbhit.h /usr/local/include/ctb-0.16
 build$ sudo ldconfig
 
->>>>>>> .r1094
-Build codec2-dev
-----------------
+codec2-dev
+----------
 
 1. See codec2-dev/README. No need to "make install"
 
-Build fdmdv2
-------------
+fdmdv2
+------
 
 1. svn co fdmdv2
 
@@ -141,20 +158,8 @@ TODO
     + level gauge?
 
 [ ] release clean up
-    [X] remove anything that doesn't work (menus, buttons) from GUI
-    [X] about
-    [X] src file credits
-    [X] decide on web site
-        + need edit by at least three of us
-    [X] if you press start and headphones unplugged (ie one sound card missing), it
-        shouldn't crash
-    [X] hook up squelch
-    [X] version number on GUI?  How to connect SVN verev to version?
-    [X] click tune and split
-    [X] rm loopback buttons
-
-    [ ] bug in record file on Win32
-    [ ] svn version tag?
+    [X] bug in record file on Win32
+    [X] svn version tag?
         + i.e. 1.0 etc rather than number
     [ ] waterfall
         + is graticule useful
@@ -163,22 +168,16 @@ TODO
     [ ] record/play dialogs layout
     [ ] remove/comment out debug printfs
     [ ] Credits: Mel, Tapr, Bruce,  Peter M, cesco, Dave W
-    [ ] rig control
-    [ ] data feature
-    [ ] always on top option
     [ ] linux version
-
     [ ] help about with URL (hyperlink?) to web site
     [ ] do we keep/put effort into getting working ./configure && Makefile?
-    [-] test with simulated AWGN/burst error channels
+    [ ] test with simulated AWGN/burst error channels
         + see if sync needs tuning to not fall over too quickly
         + nasty noises
     [ ] buffer sizes, maybe make a config number
     [ ] read comments and make sure they are still valid
     [ ] tool tip help for audio config dialog
     [ ] something sensible with disabling rx when tx button is pressed?        
-    [ ] wire up level guage
-        + I think it has relevance for analog speech, demod can handle wide input ranges
     [ ] tx/rx muting for half duplex
         + dont want funny sounds during tx
     [ ] setup doc
index 2ea7f1436b1a9b8e995dd794c3415ffaa0f11aa7..9ccc8666f9824c640aba92683333fab1d4b119bf 100644 (file)
@@ -5,9 +5,13 @@
 #
 # $ make -f Makefile.linux
 
-WX_GTK_PATH=/home/david/Desktop/wxWidgets-2.9.4/build_gtk
-CODEC2_PATH=/home/david/codec2-dev
-SOX_LIB_PATH=/home/david/tmp/sox-14.4.0/src/.libs
+# EDIT THESE FOR YOUR SYSTEM ----------------------------
+
+WX_GTK_PATH=$(HOME)/wxWidgets-2.9.4/build_gtk
+CODEC2_PATH=$(HOME)/codec2-dev
+SOX_LIB_PATH=$(HOME)/sox-14.4.0/src/.libs
+
+# END EDITS ---------------------------------------------
 
 WX_CONFIG=$(WX_GTK_PATH)/wx-config
 WX_CPPFLAGS = $(shell $(WX_CONFIG) --cxxflags)
@@ -19,7 +23,7 @@ CODEC2_LIB=$(CODEC2_PATH)/src/.libs/libcodec2.a
 SOX_LIB=$(SOX_LIB_PATH)/libsox.a
 
 CPP_FLAGS = $(WX_CPPFLAGS) $(CODEC2_INC) -I. -g -Wall -O3 -DSVN_REVISION=\"$(SVN_REVISION)\" -DFREEDV_VERSION="\"$(FREEDV_VERSION)"\"
-LIBS = $(WX_LIBS) $(CODEC2_LIB) -lm -lportaudiocpp -lpthread -lsndfile /usr/lib/libsamplerate.so.0 -lctb-0.16 $(SOX_LIB)
+LIBS = $(WX_LIBS) $(CODEC2_LIB) -lm -lportaudiocpp -lpthread -lsndfile -lsamplerate -Wl,-Bstatic -lctb-0.16 -Wl,-Bdynamic $(SOX_LIB) 
 
 OBJS = topFrame.o \
 fdmdv2_main.o \
@@ -43,7 +47,7 @@ all: freedv
 freedv: $(OBJS) 
        g++ -o freedv $(OBJS) $(CPP_FLAGS) $(LIBS)
 
-%.o: %.cpp $(HDRS) Makefile.linux
+%.o: %.cpp $(HDRS)
        g++ $(CPP_FLAGS) -c $< -o $@
 
 clean:
index aa27ae6cf005805f569dff95a8c3bce82b488392..1cfff3fed1473f5bc6f6be5d786d60065e8a479d 100644 (file)
@@ -2099,9 +2099,9 @@ void txRxProcessing()
 
         n8k = resample(cbData->insrc1, in8k_short, in48k_short, FS, g_soundCard1SampleRate, N8, nsam);
 
-        // optionally save signal from radio (demod input to file).
-        // Really useful for testing and development as it allows to
-        // develop using off air signals
+        // optionally save "from radio" signal (write demod input to file)
+        // Really useful for testing and development as it allows us
+        // to repeat tests using off air signals
 
         g_mutexProtectingCallbackData.Lock();
         if (g_recFileFromRadio && (g_sfRecFile != NULL)) {
@@ -2121,9 +2121,7 @@ void txRxProcessing()
         }
         g_mutexProtectingCallbackData.Unlock();
 
-        // optionally read signal from radio (file to demod input).
-        // Really useful for testing and development as it allows to
-        // develop using off air signals
+        // optionally read "from radio" signal from file (read demod input from file)
 
         g_mutexProtectingCallbackData.Lock();
         if (g_playFileFromRadio && (g_sfPlayFileFromRadio != NULL)) {
@@ -2146,12 +2144,16 @@ void txRxProcessing()
 
         per_frame_rx_processing(cbData->rxoutfifo, g_CodecBits, cbData->rxinfifo, &g_nRxIn, &g_State, g_pCodec2);
 
-        // if demod out of sync or we are in analog mode just pass thru
-        // audio so we can hear SSB radio output as an aid to tuning
+        // Get some audio to send to headphones/speaker.  If out of
+        // sync or in analog mode we pass thru the "from radio" audio
+        // to the headphones/speaker.  When out of sync it's useful to
+        // hear the audio from the channel, e.g. as a tuning aid
 
-        if ((g_State == 0) || g_analog)
+        if ((g_State == 0) || g_analog) {
             memcpy(out8k_short, in8k_short, sizeof(short)*n8k);
+        }
         else {
+            // we are in sync so use decoded audio 
             memset(out8k_short, 0, sizeof(short)*N8);
             fifo_read(cbData->rxoutfifo, out8k_short, N8);
         }
@@ -2165,7 +2167,9 @@ void txRxProcessing()
         }
         g_mutexProtectingCallbackData.Unlock();
 
-        if (g_SquelchActive && (g_SquelchLevel > g_snr)) {
+        // note squelch automatically disabled in analog mode
+
+        if (g_SquelchActive && (g_SquelchLevel > g_snr) && !g_analog) {
             //printf("g_SquelchLevel: %f g_snr: %f\n", g_SquelchLevel, g_snr);
             memset(out8k_short, 0, sizeof(short)*N8);
         }
@@ -2190,9 +2194,9 @@ void txRxProcessing()
 
     if (g_nSoundCards == 2 ) {
 
-        // Make sure we have at least 2 frames of modulator output
-        // samples.  This locks the modulator to the sample
-        // rate of sound card 1.  We want to make sure that modulator
+        // Make sure we have at least 6 frames of modulator output
+        // samples.  This also locks the modulator to the sample rate
+        // of sound card 1.  We want to make sure that modulator
         // samples are uninterrupted by differences in sample rate
         // between this sound card and sound card 2.
 
@@ -2217,6 +2221,7 @@ void txRxProcessing()
             nout = resample(cbData->insrc2, in8k_short, in48k_short, FS, g_soundCard2SampleRate, 2*N8, nsam);
 
             // optionally use file for mic input signal
+
             g_mutexProtectingCallbackData.Lock();
             if (g_playFileToMicIn && (g_sfPlayFile != NULL)) {
                 int n = sf_read_short(g_sfPlayFile, in8k_short, nout);
@@ -2232,7 +2237,8 @@ void txRxProcessing()
             }
             g_mutexProtectingCallbackData.Unlock();
 
-            // Opional Mic In EQ Filtering, need mutex as filter can change at run time
+            // Optional Mic In EQ Filtering, need mutex as filter can change at run time
+
             g_mutexProtectingCallbackData.Lock();
             if (cbData->micInEQEnable) {
                 sox_biquad_filter(cbData->sbqMicInBass, in8k_short, in8k_short, nout);
@@ -2243,8 +2249,24 @@ void txRxProcessing()
 
             resample_for_plot(g_plotSpeechInFifo, in8k_short, nout);
 
-            if (g_analog)
-                memcpy(out8k_short, in8k_short,  2*N8*sizeof(short));
+            if (g_analog) {
+
+                // Boost the "from mic" -> "to radio" audio in analog
+                // mode.  The need for the gain was found by
+                // experiment - analog SSB sounded too quiet compared
+                // to digital. With digital voice we generally drive
+                // the "to radio" (SSB radio mic input) at about 25%
+                // of the peak level for normal SSB voice. So we
+                // introduce 6dB gain to make analog SSB sound the
+                // same level as the digital.  Watch out for clipping.
+
+                for(int i=0; i<2*N8; i++) {
+                    float out = (float)in8k_short[i]*2.0;
+                    if (out > 32767) out = 32767.0;
+                    if (out < -32767) out = -32767.0;
+                    out8k_short[i] = out;
+                }
+            }
             else
                 per_frame_tx_processing(out8k_short, in8k_short, g_pCodec2);
  
index 2ad1fb155b9329a1921bac9858492a380ec418a1..f2368a51fbad67adca006cfcbb8dcfa587f27560 100644 (file)
@@ -340,16 +340,21 @@ void PlotWaterfall::plotPixelData()
     // update min and max amplitude estimates
 
     float max_mag = MIN_MAG_DB;
-    for(int i=0; i<FDMDV_NSPEC; i++) {
+
+    int min_fft_bin=((float)200/FDMDV_MAX_F_HZ)*FDMDV_NSPEC;
+    int max_fft_bin=((float)2800/FDMDV_MAX_F_HZ)*FDMDV_NSPEC;
+
+    for(int i=min_fft_bin; i<max_fft_bin; i++) {
         if (g_avmag[i] > max_mag)
             max_mag = g_avmag[i];
     }
+
     m_max_mag = BETA*m_max_mag + (1 - BETA)*max_mag;
     m_min_mag = max_mag - 20.0;
     //printf("max_mag: %f m_max_mag: %f\n", max_mag, m_max_mag);
     //intensity_per_dB  = (float)256 /(MAX_MAG_DB - MIN_MAG_DB);
     intensity_per_dB  = (float)256 /(m_max_mag - m_min_mag);
-    spec_index_per_px = ((float)MAX_F_HZ/(float)FDMDV_MAX_F_HZ)*(float)FDMDV_NSPEC / (float) m_rGrid.GetWidth();
+    spec_index_per_px = ((float)(MAX_F_HZ)/(float)FDMDV_MAX_F_HZ)*(float)FDMDV_NSPEC / (float) m_rGrid.GetWidth();
 
     /*
     printf("h %d w %d px_per_sec %d dy %d dy_blocks %d spec_index_per_px: %f\n", 
@@ -422,17 +427,13 @@ void PlotWaterfall::plotPixelData()
                 p.Blue() = intensity;       
                 break;
             case 2:
-                if (intensity > 250) {
-                    p.Red() = intensity;
-                    p.Green() = intensity;
-                    p.Blue() = intensity;
-                }
-                else {
-                    p.Red() = 0;
-                    p.Green() = 0;
-                    p.Blue() = intensity;
-                }
-                    
+                p.Red() = intensity;
+                p.Green() = intensity;
+                if (intensity < 127)
+                    p.Blue() = intensity*2;
+                else
+                    p.Blue() = 255;
+                        
                 break;
             }
             ++p;