Created by David Rowe
Oct 14 2012
+Linux usage Notes
+=================
+
+1. Config is stored in ~/.FMDV2, rm this file to restore defaults
+
+
BUILDING fdmdv2 for Linux
=========================
1. Download wxWidgets 2.9.4 or later and untar
-2. Build the gtk version:
-
+2. Install GTK development files (e.g. on Ubuntu libgtk2.0-dev)
+
+3. Build the gtk version:
+
$ cd wxWidgets-2.9.4
$ mkdir build_gtk
$ cd build_gtk
$ ../configure
$ make
-3. You don't actually have to "make install" wxWidgets (unless you
+4. You don't actually have to "make install" wxWidgets (unless you
really want to), it can be used by fdmdv2 out of the directory you
build it in.
Build portaudio
---------------
-1. Download and untar pa_stable_V19
+1. Make sure ALSA development support (libasound and headers) is
+ present. Portaudio will work with OSS but I found I couldn't
+ adjust the mic gain using OSS. On a modern version of Ubuntu the
+ ALSA libs can be installed with:
+
+ sudo apt-get install libasound-dev
-2. Build with C++ enabled
+ 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
+ gain.
+
+2. Download and untar pa_stable_V19
+
+3. Configure with C++ enabled:
$ ./configure --enable-cxx
- $ make
-3. I did a "sudo make install" on this, and removed the default
- Unbuntu portaudio libs as they were an earlier version. It's
- probably possible to build fdmdv2 without "make install".
+ <snip>:
+
+ Configuration summary:
+
+ Target ...................... i686-pc-linux-gnu
+ C++ bindings ................ yes
+ Debug output ................ no
+
+ ALSA ........................ yes
+ ASIHPI ...................... no
+
+ OSS ......................... yes
+ JACK ........................ no
+
+4. $ make
+
+5. You can test Portaudio with bin/pa_devs & bin/patest_sine8.
+
+6. I used a "sudo make install", and removed the default Unbuntu
+ portaudio libs as they were an earlier version. It's probably
+ possible to build fdmdv2 without "make install", by passing
+ --prefix to the ./configure stage.
Build codec2-dev
----------------
make -f Makefile.linux
+TODO
+====
+
+[ ] Stopping Waterfall
+ + When Stop pressed lower 25% of Waterfall isn't erased
+[ ] Axis labels on Waterfall incorrect
+[ ] CPU load very high for waterfall, proportional to screen size
+[X] resizing Waterfall
+ + bit map is used for memory of waterfall, so resizing will cause some
+ probs as previous memory will be for a different size
+ + so if we resize, need to delete old memory, zero new bit map
+[ ] minimum window size so we don't lose buttons and get waterfall/spectrum text
+ pressed together
+[ ] tell take lights for over/underflow realtime type issues
+[ ] lights for clipping of audio input/ouput
+
+IDEAS
+=====
+
+1. Tabbed page option that draws block diagram of system and draws line
+between sound devices and modem blocks. Lines move depending if we
+are in sync, audio pass thru etc
+
+2. On sound device for each "port" make a file one of the options, so we can
+
+3. (Thomas Kocourek n4fwd) Context sesnitive help.
+
+4. Look at how people hook up and use program, stop common mistakes or assumptions
+
+5. speech Waveform I/O. Look for clipping
+
CODEC2_INC=-I$(CODEC2_PATH)/src
CODEC2_LIB=$(CODEC2_PATH)/src/.libs/libcodec2.a
-CPP_FLAGS = $(WX_CPPFLAGS) $(CODEC2_INC) -I../extern/include -g -Wall
+CPP_FLAGS = $(WX_CPPFLAGS) $(CODEC2_INC) -I../extern/include -g -Wall -O3
LIBS = $(WX_LIBS) $(CODEC2_LIB) -lm -lportaudiocpp -lpthread -lsndfile
OBJS = topFrame.o \
fdmdv2: $(OBJS)
g++ -o fdmdv2 $(OBJS) $(CPP_FLAGS) $(LIBS)
-%.o: %.cpp $(HDRS)
+%.o: %.cpp $(HDRS) Makefile.linux
g++ $(CPP_FLAGS) -c $< -o $@
// (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_X_MAX 3.0
-#define SCATTER_Y_MAX 3.0
+#define SCATTER_X_MAX 4.0
+#define SCATTER_Y_MAX 4.0
// sample rate I/O & conversion constants
#define MAX_FPB 2048 // maximum value of portAudio framesPerBuffer
-#define PA_FPB 512 // nominal value of portAudio framesPerBuffer
+#define PA_FPB 1024 // nominal value of portAudio framesPerBuffer
#define SAMPLE_RATE 48000 // 48 kHz sampling rate rec. as we can trust accuracy of sound card
#define N8 FDMDV_NOM_SAMPLES_PER_FRAME // processing buffer size at 8 kHz
#define MEM8 (FDMDV_OS_TAPS/FDMDV_OS)
//-------------------------------------------------------------------------
// rxCallback()
//-------------------------------------------------------------------------
+
+/*
+ todo:
+
+ + add tests to determine if we have real time audio I/O problems,
+ for example lost samples, buffer overflow, too slow processing
+ + should flag the user so they can tune the system
+ + maybe compute time spent doing demod compared to time between calls
+*/
+
int MainFrame::rxCallback(
const void *inputBuffer,
void *outputBuffer,
short in48k_short[N48];
short indata[MAX_FPB];
short outdata[MAX_FPB];
+ int ret;
(void) timeInfo;
(void) statusFlags;
+ //if (statusFlags)
+ // printf("0x%x\n", statusFlags);
+
assert(inputBuffer != NULL);
assert(outputBuffer != NULL);
/*
decimation. As we can't guarantee the size of framesPerBuffer
we do a little FIFO buffering.
*/
-
+
// assemble a mono buffer (just use left channel) and write to FIFO
assert(framesPerBuffer < MAX_FPB);
for(i = 0; i < framesPerBuffer; i++, rptr += 2)
{
indata[i] = *rptr;
}
- fifo_write(cbData->infifo, indata, framesPerBuffer);
-
+ ret = fifo_write(cbData->infifo, indata, framesPerBuffer);
+ assert(ret != -1);
+
// while we have enough samples available ...
while (fifo_read(cbData->infifo, in48k_short, N48) == 0)
{
}
g_nInputBuf += FDMDV_NOM_SAMPLES_PER_FRAME;
per_frame_rx_processing(g_pRxOutBuf, &g_nOutputBuf, g_CodecBits, g_RxInBuf, &g_nInputBuf, &g_nRxIn, &g_State, g_pCodec2);
- //cbData->pWFPanel->m_newdata = true;
- //cbData->pSPPanel->m_newdata = true;
- // if demod out of sync copy input audio from A/D to aid in tuning
+ // prepare output buffer for D/A (speaker)
if (g_nOutputBuf >= N8)
{
+ // if demod out of sync copy input audio from A/D to aid in tuning
if(g_State == 0)
{
for(i = 0; i < N8; i++)
{
- in8k[MEM8 + i] = out8k[i]; // A/D signal
+ in8k[MEM8 + i] = out8k[i]; // echo A/D signal
}
}
else
// have enough samples to run demod twice.
//
// With a +/- 10 Hz sample clock difference at FS=8000Hz (+/- 1250
- // ppm), case 0 or 1 occured about once every 30 seconds. This is
+ // ppm), case 0 or 2 occured about once every 30 seconds. This is
// no problem for the decoded audio.
//
while(*n_input_buf >= *nin)
fdmdv_get_rx_spectrum(g_pFDMDV, rx_spec, rx_fdm, nin_prev);
fdmdv_get_demod_stats(g_pFDMDV, &g_stats);
- // Average Data
+ // Average rx spectrum data using a simple IIR low pass filter
for(i = 0; i < FDMDV_NSPEC; i++)
{
g_avmag[i] = (1.0 - BETA) * g_avmag[i] + BETA * rx_spec[i];