From 085a195fac8f378ef4a3dffc77bbe9347b058e9e Mon Sep 17 00:00:00 2001 From: drowe67 Date: Sat, 1 Dec 2012 04:06:23 +0000 Subject: [PATCH] first pass at real time update of MicIn spectrum in response to slider git-svn-id: https://svn.code.sf.net/p/freetel/code@1102 01035d8c-6547-0410-b346-abe4f91aad63 --- fdmdv2/README.linux | 61 ++++++++++++++----- fdmdv2/src/Makefile.linux | 8 ++- fdmdv2/src/dlg_filter.cpp | 91 +++++++++++++++++++++++++++-- fdmdv2/src/dlg_filter.h | 5 ++ fdmdv2/src/fdmdv2_main.cpp | 5 +- fdmdv2/src/fdmdv2_plot_spectrum.cpp | 10 +++- fdmdv2/src/fdmdv2_plot_spectrum.h | 4 +- fdmdv2/src/sox_biquad.c | 4 +- fdmdv2/src/sox_biquad.h | 2 +- 9 files changed, 159 insertions(+), 31 deletions(-) diff --git a/fdmdv2/README.linux b/fdmdv2/README.linux index 4233bc92..90a6fa66 100644 --- a/fdmdv2/README.linux +++ b/fdmdv2/README.linux @@ -73,6 +73,24 @@ Build portaudio possible to build fdmdv2 without "make install", by passing --prefix to the ./configure stage. +<<<<<<< .mine +Build libsox +------------ + +We use some of the internal sox functions for the equaliser feature. + +wget http://sourceforge.net/projects/sox/files/sox/14.4.0/sox-14.4.0.tar.gz/download +tar xvzf sox-14.4.0.tar.gz +cd sox-14.4.0 + +Now we only want to use a few internal functions of sox. This +configure line mkes sure we don't build in unneeded depednancies: + +sox-14.4.0$ ./configure --enable-shared=no --without-id3tag --without-png --disable-gomp --with-oggvorbis=no --with-oss=no --with-flac=no --disable-dl-sndfile + +sox-14.4.0$ make + +======= Build libctb (Communications Toolbox) ------------------------------------- @@ -87,6 +105,7 @@ 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 ---------------- @@ -125,34 +144,44 @@ TODO [X] remove anything that doesn't work (menus, buttons) from GUI [X] about [X] src file credits - [ ] decide on web site + [X] decide on web site + need edit by at least three of us - [ ] help about with URL (hyperlink?) to web site - [ ] if you press start and headphones unplugged (ie one sound card missing), it + [X] if you press start and headphones unplugged (ie one sound card missing), it shouldn't crash - [ ] do we keep/put effort into getting working ./configure && Makefile? + [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? + + i.e. 1.0 etc rather than number + [ ] waterfall + + is graticule useful + + peaks showing + + showing fades properly + [ ] record/play dialogs layout [ ] remove/comment out debug printfs - [ ] hook up squelch - [ ] test with simulated AWGN/burst error channels + [ ] 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 + see if sync needs tuning to not fall over too quickly + nasty noises - [ ] version number on GUI? How to connect SVN verev to version? [ ] buffer sizes, maybe make a config number [ ] read comments and make sure they are still valid - [ ] rig control - [ ] click tune and split [ ] tool tip help for audio config dialog - [ ] rm loopback buttons [ ] 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 - [ ] data feature - + 11 or 00 sync with good inst snr - + way to measure inst snr - + drag text to "hopper". Set thresh for sending (time or mic level) [ ] tx/rx muting for half duplex + dont want funny sounds during tx - [ ] setup Readme + [ ] setup doc [ ] Donate button with hyperlink from about dialog or help menu? IDEAS @@ -206,3 +235,5 @@ What a good scatter diagram/spectrum looks like Setting up in audio loopback Explain one and two soundcard modes + +Right click drag tabs, new window, tab order diff --git a/fdmdv2/src/Makefile.linux b/fdmdv2/src/Makefile.linux index e9c7c3a8..f04e1748 100644 --- a/fdmdv2/src/Makefile.linux +++ b/fdmdv2/src/Makefile.linux @@ -7,6 +7,7 @@ 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 WX_CONFIG=$(WX_GTK_PATH)/wx-config WX_CPPFLAGS = $(shell $(WX_CONFIG) --cxxflags) @@ -14,9 +15,10 @@ WX_LIBS = $(shell $(WX_CONFIG) --libs core, base, aui, adv, net) SVN_REVISION=$(shell svnversion) CODEC2_INC=-I$(CODEC2_PATH)/src 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)\" -LIBS = $(WX_LIBS) $(CODEC2_LIB) -lm -lportaudiocpp -lpthread -lsndfile /usr/lib/libsamplerate.so.0 -lctb-0.16 +LIBS = $(WX_LIBS) $(CODEC2_LIB) -lm -lportaudiocpp -lpthread -lsndfile /usr/lib/libsamplerate.so.0 -lctb-0.16 $(SOX_LIB) OBJS = topFrame.o \ fdmdv2_main.o \ @@ -29,7 +31,9 @@ fdmdv2_pa_wrapper.o \ dlg_audiooptions.o \ dlg_comports.o \ dlg_filter.o \ -varicode.o +varicode.o \ +sox_biquad.o + HDRS = dlg_audiooptions.h dlg_comports.h dlg_filter.h fdmdv2_main.h fdmdv2_defines.h fdmdv2_plot.h fdmdv2_plot_scalar.h fdmdv2_plot_waterfall_linux.h fdmdv2_plot_scatter.h fdmdv2_plot_spectrum.h fdmdv2_pa_wrapper.h topFrame.h varicode.h diff --git a/fdmdv2/src/dlg_filter.cpp b/fdmdv2/src/dlg_filter.cpp index d9259060..088fecf6 100644 --- a/fdmdv2/src/dlg_filter.cpp +++ b/fdmdv2/src/dlg_filter.cpp @@ -19,6 +19,7 @@ // //========================================================================== #include "dlg_filter.h" +#include "sox_biquad.h" #define SLIDER_MAX 100 #define SLIDER_LENGTH 155 @@ -29,6 +30,10 @@ #define MAX_FREQ_BASS 600.00 #define MAX_FREQ_DEF 3000.00 +#define IMP_AMP 2000.0 +#define F_STEP_DFT 50.0 +#define F_MAG_N (int)(MAX_F_HZ/F_STEP_DFT) + extern struct CODEC2 *g_pCodec2; //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-= @@ -89,10 +94,16 @@ FilterDlg::FilterDlg(wxWindow* parent, bool running, wxWindowID id, const wxStri bSizer30->Add(m_auiNotebook, 0, wxEXPAND|wxALL, 3); - m_MicInFreqRespPlot = new PlotSpectrum((wxFrame*) m_auiNotebook, FILTER_MIN_MAG_DB, FILTER_MAX_MAG_DB); + m_MicInMagdB = new float[F_MAG_N]; + for(int i=0; iAddPage(m_MicInFreqRespPlot, _("Microphone In Equaliser")); - m_SpkOutFreqRespPlot = new PlotSpectrum((wxFrame*)m_auiNotebook, FILTER_MIN_MAG_DB, FILTER_MAX_MAG_DB); + m_SpkOutMagdB = new float[F_MAG_N]; + for(int i=0; iAddPage(m_SpkOutFreqRespPlot, _("Speaker Out Equaliser")); // OK - Cancel - Default Buttons at the bottom -------------------------- @@ -126,6 +137,8 @@ FilterDlg::FilterDlg(wxWindow* parent, bool running, wxWindowID id, const wxStri m_sdbSizer5Cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnCancel), NULL, this); m_sdbSizer5Default->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnDefault), NULL, this); m_sdbSizer5OK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnOK), NULL, this); + + sox_biquad_start(); } //------------------------------------------------------------------------- @@ -133,6 +146,10 @@ FilterDlg::FilterDlg(wxWindow* parent, bool running, wxWindowID id, const wxStri //------------------------------------------------------------------------- FilterDlg::~FilterDlg() { + delete m_MicInMagdB; + delete m_SpkOutMagdB; + sox_biquad_finish(); + // Disconnect Events this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(FilterDlg::OnInitDialog)); @@ -216,6 +233,10 @@ void FilterDlg::ExchangeData(int inout) // Mic In Equaliser m_MicInBass.freqHz = wxGetApp().m_MicInBassFreqHz; setFreq(&m_MicInBass); + + m_MicInFreqRespPlot->m_newdata = true; + m_MicInFreqRespPlot->Refresh(); + calcFilterSpectrum(&m_MicInBass, m_MicInMagdB); } if(inout == EXCHANGE_DATA_OUT) { @@ -258,6 +279,9 @@ void FilterDlg::OnDefault(wxCommandEvent& event) m_gamma = CODEC2_LPC_PF_GAMMA; setGamma(); m_codec2LPCPostFilterEnable->SetValue(true); m_codec2LPCPostFilterBassBoost->SetValue(true); + + m_MicInBass.freqHz = 1.0; + } //------------------------------------------------------------------------- @@ -343,10 +367,67 @@ void FilterDlg::setFreq(EQ *eq) eq->sliderFreq->SetValue(slider); } -void FilterDlg::OnMicInBassFreqScroll(wxScrollEvent& event) +void FilterDlg::sliderToFreq(EQ *eq) { - m_MicInBass.freqHz = ((float)m_MicInBass.sliderFreq->GetValue()/SLIDER_MAX)*m_MicInBass.maxFreqHz; - printf("FilterDlg::OnMicInBassFreqScroll m_MicInBass.freqHz: %f\n", m_MicInBass.freqHz); + eq->freqHz = ((float)eq->sliderFreq->GetValue()/SLIDER_MAX)*eq->maxFreqHz; + if (eq->freqHz < 1.0) eq->freqHz = 1.0; // sox deosn't like 0 Hz; setFreq(&m_MicInBass); + calcFilterSpectrum(eq, m_MicInMagdB); + m_MicInFreqRespPlot->m_newdata = true; + m_MicInFreqRespPlot->Refresh(); } +void FilterDlg::OnMicInBassFreqScroll(wxScrollEvent& event) +{ + sliderToFreq(&m_MicInBass); +} + +#define NIMP 50 + +void FilterDlg::calcFilterSpectrum(EQ *eq, float magdB[]) { + void *sbq; + const char *argv[10]; + char highpass[80]; + char freq[80]; + short in[NIMP]; + short out[NIMP]; + COMP X[(int)(MAX_F_HZ/F_STEP_DFT)]; + float f,w; + int i, k, argc; + + // find impulse response ----------------------------------- + + for(i=0; ifreqHz); argv[1] = freq; + argc=1; + //printf("argv[0]: %s argv[1]: %s\n", argv[0], argv[1]); + sbq = sox_biquad_create(argc, argv); + + sox_biquad_filter(sbq, out, in, NIMP); + //for(i=0; iSetToolTip(_("Left click to tune")); m_auiNbookCtrl->AddPage(m_panelSpectrum, _("Spectrum"), true, wxNullBitmap); } @@ -329,7 +330,7 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent) wxGetApp().m_codec2LPCPostFilterBeta = (float)pConfig->Read(wxT("/Filter/codec2LPCPostFilterBeta"), CODEC2_LPC_PF_BETA*100)/100.0; //printf("main(): m_codec2LPCPostFilterBeta: %f\n", wxGetApp().m_codec2LPCPostFilterBeta); - wxGetApp().m_MicInBassFreqHz = pConfig->Read(wxT("/Filter/MicInBassFreqHz"), 0.0); + wxGetApp().m_MicInBassFreqHz = pConfig->Read(wxT("/Filter/MicInBassFreqHz"), 1.0); wxGetApp().m_callSign = pConfig->Read("/Data/CallSign", wxT("")); diff --git a/fdmdv2/src/fdmdv2_plot_spectrum.cpp b/fdmdv2/src/fdmdv2_plot_spectrum.cpp index 705cded4..2ea8a7ce 100644 --- a/fdmdv2/src/fdmdv2_plot_spectrum.cpp +++ b/fdmdv2/src/fdmdv2_plot_spectrum.cpp @@ -45,7 +45,7 @@ END_EVENT_TABLE() // @brief // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-= -PlotSpectrum::PlotSpectrum(wxFrame* parent, float min_mag_db, float max_mag_db): PlotPanel(parent) +PlotSpectrum::PlotSpectrum(wxFrame* parent, float *magdB, int n_magdB, float min_mag_db, float max_mag_db): PlotPanel(parent) { m_greyscale = 0; m_Bufsz = GetMaxClientSize(); @@ -53,6 +53,9 @@ PlotSpectrum::PlotSpectrum(wxFrame* parent, float min_mag_db, float max_mag_db): m_firstPass = true; m_line_color = 0; SetLabelSize(10.0); + + m_magdB = magdB; + m_n_magdB = n_magdB; // number of points in magdB that covers 0 ... MAX_F_HZ of spectrum m_max_mag_db = max_mag_db; m_min_mag_db = min_mag_db; m_rxFreq = 0.0; @@ -126,7 +129,8 @@ void PlotSpectrum::draw(wxAutoBufferedPaintDC& dc) pen.SetWidth(1); dc.SetPen(pen); - index_to_px = ((float)FDMDV_MAX_F_HZ/(float)MAX_F_HZ)*(float)m_rGrid.GetWidth()/FDMDV_NSPEC; + //index_to_px = ((float)FDMDV_MAX_F_HZ/(float)MAX_F_HZ)*(float)m_rGrid.GetWidth()/FDMDV_NSPEC; + index_to_px = (float)m_rGrid.GetWidth()/m_n_magdB; mag_dB_to_py = (float)m_rGrid.GetHeight()/(m_max_mag_db - m_min_mag_db); int last_index = ((float)MAX_F_HZ/(float)FDMDV_MAX_F_HZ)*FDMDV_NSPEC; @@ -135,7 +139,7 @@ void PlotSpectrum::draw(wxAutoBufferedPaintDC& dc) for(index = 0; index < last_index; index++) { x = index*index_to_px; - mag = g_avmag[index]; + mag = m_magdB[index]; if (mag > m_max_mag_db) mag = m_max_mag_db; if (mag < m_min_mag_db) mag = m_min_mag_db; y = -(mag - m_max_mag_db) * mag_dB_to_py; diff --git a/fdmdv2/src/fdmdv2_plot_spectrum.h b/fdmdv2/src/fdmdv2_plot_spectrum.h index 1a53fd4c..94a04ce0 100644 --- a/fdmdv2/src/fdmdv2_plot_spectrum.h +++ b/fdmdv2/src/fdmdv2_plot_spectrum.h @@ -30,7 +30,7 @@ class PlotSpectrum : public PlotPanel { public: - PlotSpectrum(wxFrame* parent, float min_mag_db=MIN_MAG_DB, float max_mag_db=MAX_MAG_DB); + PlotSpectrum(wxFrame* parent, float *magdB, int n_magdB, float min_mag_db=MIN_MAG_DB, float max_mag_db=MAX_MAG_DB); ~PlotSpectrum(); void setRxFreq(float rxFreq) { m_rxFreq = rxFreq; } @@ -46,6 +46,8 @@ class PlotSpectrum : public PlotPanel float m_rxFreq; float m_max_mag_db; float m_min_mag_db; + float *m_magdB; + int m_n_magdB; DECLARE_EVENT_TABLE() }; diff --git a/fdmdv2/src/sox_biquad.c b/fdmdv2/src/sox_biquad.c index 0a3ff857..5687d8f8 100644 --- a/fdmdv2/src/sox_biquad.c +++ b/fdmdv2/src/sox_biquad.c @@ -55,14 +55,14 @@ void sox_biquad_finish(void) argv[0] = "highpass"; argv[1]="1000"; argc=1; */ -void *sox_biquad_create(int argc, char *argv[]) +void *sox_biquad_create(int argc, const char *argv[]) { int ret; sox_effect_t *e; int (*start)(sox_effect_t *); /* function pointer to effect start func */ e = sox_create_effect(sox_find_effect(argv[0])); assert(e != NULL); - assert(sox_effect_options(e, argc, &argv[1]) == SOX_SUCCESS); + assert(sox_effect_options(e, argc, (char * const*)&argv[1]) == SOX_SUCCESS); start = e->handler.start; e->in_signal.rate = 8000; /* locked at FS=8000 Hz */ diff --git a/fdmdv2/src/sox_biquad.h b/fdmdv2/src/sox_biquad.h index 5ec70bed..f38de642 100644 --- a/fdmdv2/src/sox_biquad.h +++ b/fdmdv2/src/sox_biquad.h @@ -29,7 +29,7 @@ extern "C" { void sox_biquad_start(void); void sox_biquad_finish(void); -void *sox_biquad_create(int argc, char *argv[]); +void *sox_biquad_create(int argc, const char *argv[]); void sox_biquad_destroy(void *sbq); void sox_biquad_filter(void *sbq, short out[], short in[], int n); -- 2.25.1