Upstream version 1.35L

pull/2/head
Stelios Bounanos 2007-06-22 23:24:50 +01:00
rodzic e37ebe13a4
commit 33f4b49107
15 zmienionych plików z 455 dodań i 311 usunięć

Wyświetl plik

@ -9,6 +9,18 @@ Change Log:
7) Added PSKmail tab and control to allow disabling the automatic
return to the PSK sweet spot if running a mail server
8) Added "Save To" menu item on received text popup menu.
9) Added relative sizing of Rx / Tx text widgets to state memory
10) Added hidden Menus "Test / Capture / Generate / Playback"
Capture - captures current audio input stream to file "capture.snd"
Generate - sends current audio output stream to file "generate.snd"
Playback - reads audio stream from file "playback.snd" in lieu of
the audio sound card
These provide the ability to make repetitive tests of various modems
by playing back a known audio stream.
If you capture an audio stream and then copy the file to playback.snd
you can then play that audio stream back. The stream will loop repitively
until the playback is turned off.
The three menu items, Capture, Generate and Playback are all toggle menu items.
1.34 1) Cleaned up unused code segments
2) Modified CW decoder to allow setting upper and lower limits on
Tx WPM

46
INSTALL
Wyświetl plik

@ -1,46 +0,0 @@
A single makefile is used to create various compile strategies for fldigi
make
builds fldigi with hamlib support
make clean
removes all vestiges of prior builds
make CFG=hamlib-debug
builds fldigi with hamlib support and gdb debug information
make CFG=hamlib-local
builds fldigi with hamlib support and fltk_jpeg, fltk_png and
fltk_z compiled into the fltk library
make CFG=nhl
builds fldigi without hamlib support
make CFG=nhl-debug
builds fldigi without hamlib supoort but with gdb debug
information
make CFG=nhl-local
builds fldigi without hamlib support but with fltk_jpeg, fltk_png
and fltk_z compiled into the fltk library
All make's place the object files in ./Objects and the target executable
in ./Install
The ./Install directory also contains icons suitable for both desktop and
menu use.
Copy the executable file fldigi to a directory that your shell can routinely
access for executable files. I have a ~/bin directory that holds all of my
local executables.
If you plan on using fldigi with pskmail then you should create a separate
directory with a single file in it to start:
o PSKmailclient, or PSKmailserver, depending on your desired pskmail
service.
o then you should execute Fldigi from this directory, preferably from
a terminal window
After first use you will find a $HOME/.fldigi directory created with
all of the files needed for fldigi to run and be configured.

Wyświetl plik

@ -25,7 +25,7 @@
#ifndef _CONFIG_H
#define _CONFIG_H
// You can change the width of the waterfall / spectrum display by modifying this
// You can change the x1 width of the waterfall / spectrum display by modifying this
// constant.
// Suggest that you make the value a multiple of 100.
// DO NOT EXCEED 4000
@ -34,5 +34,58 @@
#define IMAGE_WIDTH 3000
// widget sizes internal to the waterfall widget
#define BEZEL 2
#define WFTEXT 10
#define WFSCALE 10
#define WFMARKER 6
#define BTN_HEIGHT 20
// use the following for EmComm minimal footprint
//#define Hwfall 120
//#define WMINIMUM (Hwfall + 580)
//#define HNOM 450 // do not make smaller than 400
//#define WNOM WMINIMUM
// use the following for the original fldigi waterfall sizing
#define Hwfall 140
#define WMINIMUM (IMAGE_WIDTH / 4 + Hwfall - BTN_HEIGHT)
#define HNOM 570
#define WNOM WMINIMUM
#define bwColor 30
#define bwFFT 30
#define bwX1 30
#define bwMov 20
#define cwCnt 100
#define cwRef 50
#define cwMode 85
#define bwQsy 45
#define bwRate 45
#define bwXmtLock 45
#define bwRev 45
#define bwXmtRcv 45
#define wSpace 2
#define Hmenu 22
#define Hqsoframe 48
#define Hnotes 22
#define Hstatus 22
#define Hmacros 22
#define Htext (HNOM - 4 - Hwfall - Hmenu - Hstatus - Hmacros - Hqsoframe - Hnotes)
#define Hxmttxt (Htext) / 4
#define Hrcvtxt (Htext - (Hxmttxt))
#define Wwfall (WNOM - Hwfall + BTN_HEIGHT + 2 * BEZEL)
#define Wmode 80
#define Ws2n 100
#define Wimd 100
#define Wwarn 16
#define bwAfcOnOff (Hwfall -22)/2
#define bwSqlOnOff (Hwfall -22)/2
#define Wstatus (WNOM - Wmode - Ws2n - Wimd - Wwarn - bwAfcOnOff - bwSqlOnOff)
#endif

Wyświetl plik

@ -30,12 +30,10 @@
#include <FL/fl_ask.H>
#include <FL/Fl_Pixmap.H>
#include <FL/Fl_Image.H>
#include <FL/Fl_Tile.H>
#include "version.h"
#include "waterfall.h"
#include "raster.h"
#include "main.h"
#include "threads.h"
#include "trx.h"
@ -80,7 +78,6 @@ cMixer mixer;
Fl_Button *btnTune = (Fl_Button *)0;
Fl_Tile *TiledGroup = (Fl_Tile *)0;
//Fl_Group *TiledGroup = (Fl_Group *)0;
TextView *ReceiveText=(TextView *)0;
TextEdit *TransmitText=(TextEdit *)0;
Fl_Text_Buffer *rcvBuffer = (Fl_Text_Buffer *)0;
@ -118,7 +115,6 @@ bool altMacros = false;
bool bSaveFreqList = false;
string strMacroName[10];
waterfall *wf = (waterfall *)0;
Digiscope *digiscope = (Digiscope *)0;
Fl_Slider *sldrSquelch = (Fl_Slider *)0;
@ -662,6 +658,31 @@ void cb_mnuConfigModems(Fl_Menu_*, void*) {
dlgConfig->show();
}
bool capval = false;
void cb_mnuCapture(Fl_Menu_ *m, void *d)
{
if (!scard) return;
capval = !capval;
scard->Capture(capval);
}
bool genval = false;
void cb_mnuGenerate(Fl_Menu_ *m, void *d)
{
if (!scard) return;
genval = !genval;
scard->Generate(genval);
}
bool playval = false;
void cb_mnuPlayback(Fl_Menu_ *m, void *d)
{
if (!scard) return;
playval = !playval;
scard->Playback(playval);
}
void cb_FontBrowser(Font_Browser*, void* v)
{
Font_Browser *ft= (Font_Browser*)v;
@ -987,10 +1008,15 @@ Fl_Menu_Item menu_[] = {
{" ", 0, 0, 0, FL_MENU_INACTIVE, FL_NORMAL_LABEL, 0, 14, 0}, // 57
{"Rig", 0, (Fl_Callback*)cb_mnuRig, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, // 58
{" ", 0, 0, 0, FL_MENU_INACTIVE, FL_NORMAL_LABEL, 0, 14, 0}, // 59
{"Help", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0}, // 60
{"About", 0, (Fl_Callback*)cb_mnuAbout, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, // 61
{0,0,0,0,0,0,0,0,0}, // 62
{0,0,0,0,0,0,0,0,0}, // 63
{"Test", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0}, // 60
{"Capture", 0, (Fl_Callback*)cb_mnuCapture, 0, FL_MENU_TOGGLE, FL_NORMAL_LABEL, 0, 14, 0}, // 61
{"Generate", 0, (Fl_Callback*)cb_mnuGenerate, 0, FL_MENU_TOGGLE, FL_NORMAL_LABEL, 0, 14, 0}, // 62
{"Playback", 0, (Fl_Callback*)cb_mnuPlayback, 0, FL_MENU_TOGGLE, FL_NORMAL_LABEL, 0, 14, 0}, // 63
{0,0,0,0,0,0,0,0,0}, // 64
{"Help", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0}, // 65
{"About", 0, (Fl_Callback*)cb_mnuAbout, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, // 66
{0,0,0,0,0,0,0,0,0}, // 67
{0,0,0,0,0,0,0,0,0}, // 68
};
Fl_Menu_Bar *mnu;
@ -1009,6 +1035,16 @@ void activate_rig_menu_item(bool b)
mnu->redraw();
}
void activate_test_menu_item(bool b)
{
if (b)
menu_[60].show();
else
menu_[60].hide();
mnu->redraw();
}
void create_fl_digi_main() {
int Y = 0;
fl_digi_main = new Fl_Double_Window(WNOM, HNOM, "fldigi");
@ -1076,14 +1112,16 @@ void create_fl_digi_main() {
int sw = 15;
Fl_Group *MixerFrame = new Fl_Group(0,Y,sw, Hrcvtxt + Hxmttxt);
valRcvMixer = new Fl_Slider(0, Y, sw, (Hrcvtxt + Hxmttxt)/2 - 15, "R");
// valRcvMixer = new Fl_Slider(0, Y, sw, (Htext)/2 - 15, "R");
valRcvMixer = new Fl_Slider(0, Y, sw, (Htext)/2, "");
valRcvMixer->type(FL_VERT_NICE_SLIDER);
valRcvMixer->color(fl_rgb_color(0,110,30));
valRcvMixer->labeltype(FL_ENGRAVED_LABEL);
valRcvMixer->selection_color(fl_rgb_color(255,255,0));
valRcvMixer->range(1.0,0.0);
valRcvMixer->callback( (Fl_Callback *)cb_RcvMixer);
valXmtMixer = new Fl_Slider(0, Y + (Hrcvtxt + Hxmttxt)/2, sw, (Hrcvtxt + Hxmttxt)/2 - 15, "T");
// valXmtMixer = new Fl_Slider(0, Y + (Htext)/2, sw, (Htext)/2 - 15, "T");
valXmtMixer = new Fl_Slider(0, Y + (Htext)/2, sw, (Htext)/2, "");
valXmtMixer->type(FL_VERT_NICE_SLIDER);
valXmtMixer->color(fl_rgb_color(110,0,30));
valXmtMixer->labeltype(FL_ENGRAVED_LABEL);
@ -1094,9 +1132,8 @@ void create_fl_digi_main() {
valXmtMixer->deactivate();
MixerFrame->end();
Fl_Tile *TiledGroup = new Fl_Tile(sw, Y, WNOM-sw, Hrcvtxt + Hxmttxt);
// Fl_Group *TiledGroup = new Fl_Group(sw, Y, WNOM-sw, Hrcvtxt + Hxmttxt);
Fl_Box *minbox = new Fl_Box(sw,Y + 66, WNOM-sw, Hxmttxt + Hrcvtxt - 66 - 32);
Fl_Tile *TiledGroup = new Fl_Tile(sw, Y, WNOM-sw, Htext);
Fl_Box *minbox = new Fl_Box(sw,Y + 66, WNOM-sw, Htext - 66 - 32);
minbox->hide();
ReceiveText = new TextView(sw, Y, WNOM-sw, Hrcvtxt, "");
@ -1141,19 +1178,23 @@ void create_fl_digi_main() {
wfpack->type(1);
wf = new waterfall(0, Y, Wwfall, Hwfall);
wf->end();
Fl_Pack *ypack = new Fl_Pack(WNOM-(Hwfall-22), Y, Hwfall-22, Hwfall);
int Wscope = Hwfall - BTN_HEIGHT - 2 * BEZEL;
Fl_Pack *ypack = new Fl_Pack( WNOM - Wscope, Y,
Wscope, Hwfall);
ypack->type(0);
digiscope = new Digiscope (WNOM-(Hwfall-22), Y, Hwfall-22, Hwfall-22);
digiscope = new Digiscope ( WNOM - Wscope, Y,
Wscope,
Wscope);
pgrsSquelch = new Fl_Progress(
WNOM-(Hwfall-22), Y + Hwfall - 22,
Hwfall - 22, 10, "");
WNOM - Wscope, Y + Wscope,
Wscope, (BTN_HEIGHT + 2*BEZEL) / 2, "");
pgrsSquelch->color(FL_BACKGROUND2_COLOR, FL_DARK_GREEN);
sldrSquelch = new Fl_Slider(
FL_HOR_NICE_SLIDER,
WNOM-(Hwfall-22), Y + Hwfall - 12,
Hwfall - 22, 12, "");
WNOM - Wscope, Y + Wscope + BEZEL + (BTN_HEIGHT + 2*BEZEL) / 2,
Wscope, (BTN_HEIGHT + 2*BEZEL) / 2, "");
sldrSquelch->minimum(0);
sldrSquelch->maximum(100);
@ -1237,7 +1278,6 @@ void display_metric(double metric)
void put_cwRcvWPM(double wpm)
{
// if (!prgsCWrcvWPM) return;
int U = progdefaults.CWupperlimit;
int L = progdefaults.CWlowerlimit;
double dWPM = 100.0*(wpm - L)/(U - L);

Wyświetl plik

@ -37,9 +37,12 @@
#include <FL/Fl_Slider.H>
#include <FL/Fl_Progress.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Tile.H>
#include "combo.h"
#include "TextView.h"
#include "raster.h"
#include "waterfall.h"
#include "digiscope.h"
#include "globals.h"
@ -50,6 +53,8 @@ extern cMixer mixer;
extern TextView *ReceiveText;
extern TextEdit *TransmitText;
extern Raster *FHdisp;
extern Fl_Tile *TiledGroup;
extern Fl_Text_Buffer *rcvBuffer;
extern Fl_Text_Buffer *xmtBuffer;
extern Fl_Box *StatusBar;
@ -78,9 +83,6 @@ extern Fl_Slider *valXmtMixer;
extern bool altMacros;
//extern Fl_Browser *ReceiveText;
//extern Fl_Browser *TransmitText;
extern waterfall *wf;
extern Digiscope *digiscope;
@ -88,6 +90,7 @@ extern Digiscope *digiscope;
extern void create_fl_digi_main();
extern Fl_Menu_Item menu_[];
extern void activate_rig_menu_item(bool b);
extern void activate_test_menu_item(bool b);
extern void put_freq(double frequency);
extern void put_Bandwidth(int bandwidth);

Wyświetl plik

@ -21,30 +21,6 @@
#include "rigclass.h"
#endif
#define Hmenu 24
#define Hqsoframe 48
#define Hnotes 24
#define Hrcvtxt 200
#define Hxmttxt 100
//#define Hrcvtxt 160
//#define Hxmttxt 100
#define Hwfall 140
//#define Hwfall 118
#define Hstatus 22
#define Hmacros 24
#define Wmode 80
#define Ws2n 100
#define Wimd 100
#define Wwarn 16
#define bwAfcOnOff (Hwfall -22)/2
#define bwSqlOnOff (Hwfall -22)/2
#define Wwfall 754
//#define Wwfall 654
#define HNOM (Hwfall + Hxmttxt + Hrcvtxt + Hmenu + (Hstatus + 4) + Hmacros + Hqsoframe + Hnotes)
#define WNOM (Wwfall + Hwfall - 22)
#define Wstatus (WNOM - Wmode - Ws2n - Wimd - Wwarn - bwAfcOnOff - bwSqlOnOff)
extern Fl_Mutex trx_mutex;
extern Fl_Cond trx_cond;
@ -55,6 +31,7 @@ extern string HomeDir;
extern string PskMailDir;
extern string xmlfname;
extern bool gmfskmail;
extern bool testmenu;
extern std::string scDevice;
extern PTT *push2talk;

Wyświetl plik

@ -16,6 +16,7 @@
#include <math.h>
#include <iostream>
#include <fstream>
#include <string>
#include "samplerate/samplerate.h"
@ -28,6 +29,8 @@
#define SND_BUF_LEN 65536
//#define SRC_BUF_LEN (8*SND_BUF_LEN)
using namespace std;
class SndException {
public:
char szError[80];
@ -59,6 +62,10 @@ private:
int mode;
bool formatok;
bool capture;
bool playback;
bool generate;
void getVersion();
void getCapabilities();
void getFormats();
@ -77,10 +84,19 @@ private:
float *snd_buffer;
float *src_buffer;
unsigned char *cbuff;
ofstream ofGenerate;
ofstream ofCapture;
fstream ifPlayback;
void writeGenerate(double *buff, int count);
void writeCapture(double *buff, int count);
int readPlayback(double *buff, int count);
public:
cSound(const char *dev = "/dev/dsp");
~cSound();
int Open(int mode, int freq = 8000);
int Open(int mode, int freq = 8000, int nchan = 2);
void Close();
int Write(unsigned char *, int);
int write_samples(double *, int);
@ -95,6 +111,10 @@ public:
int Channels() { return channels;};
int Format() { return play_format;};
bool FormatOK() { return formatok;};
void Capture(bool on);
void Playback(bool on);
void Generate(bool on);
};
#endif

Wyświetl plik

@ -17,6 +17,7 @@ struct status {
int mainY;
int mainW;
int mainH;
int RxTextHeight;
bool rigShown;
int rigX;
int rigY;

Wyświetl plik

@ -1,6 +1,6 @@
#ifndef _VERSION_H
#define _VERSION_H
#define FLDIGI_VERSION "1.35J"
#define FLDIGI_VERSION "1.35L"
#endif

Wyświetl plik

@ -61,28 +61,6 @@
#define FFT_LEN 4096
#define SC_SMPLRATE 8000
#define BEZEL 2
#define WFTEXT 10
#define WFSCALE 10
#define WFMARKER 6
#define BTN_HEIGHT 20
#define bwColor 35
#define bwFFT 35
#define bwX1 25
#define bgX14 75
#define bwMov 20
#define bgMov 60
#define cwCnt 120
#define cwRef 60
#define cwMode 85
#define bwQsy 45
#define bwRate 45
#define bwXmtLock 45
#define bwRev 45
#define bwXmtRcv 60
#define wSpace 4
#define fftabs(a,b) sqrt((a)*(a) + (b)*(b))
struct RGB {

Wyświetl plik

@ -54,7 +54,7 @@ string PskMailFile;
string HomeDir;
string xmlfname;
bool gmfskmail = false;
bool testmenu = false;
PTT *push2talk = (PTT *)0;
#ifndef NOHAMLIB
@ -63,6 +63,7 @@ Rig *xcvr = (Rig *)0;
cLogfile *logfile = 0;;
bool gmfskmail = false;
cLogfile *Maillogfile = (cLogfile *)0;
FILE *server;
FILE *client;
@ -128,8 +129,15 @@ int main(int argc, char ** argv) {
fl_register_images();
Fl::set_fonts(0);
if (argc == 2)
if (strcasecmp(argv[1], "TEST") == 0)
testmenu = true;
rigcontrol = createRigDialog();
create_fl_digi_main();
activate_test_menu_item(testmenu);
createConfig();
macros.loadDefault();
@ -144,11 +152,7 @@ int main(int argc, char ** argv) {
progdefaults.btnRTSDTRis,
progdefaults.btnPTTREVis );
if (argc == 2)
scDevice = argv[1];
else
scDevice = progdefaults.SCdevice;
trx_start(scDevice.c_str());
progdefaults.initInterface();

Wyświetl plik

@ -26,6 +26,7 @@ status progStatus = {
0, // int mainY;
WNOM, // int mainW;
HNOM, // int mainH;
Hrcvtxt, // int RxTextHeight;
false, // bool rigShown;
0, // int rigX;
0, // int rigY;
@ -43,6 +44,7 @@ void status::saveLastState()
mainY = fl_digi_main->y();
mainW = fl_digi_main->w();
mainH = fl_digi_main->h();
RxTextHeight = ReceiveText->h();
if (rigcontrol)
if (rigcontrol->visible()) {
rigShown = rigcontrol->visible();
@ -60,6 +62,7 @@ void status::saveLastState()
deffile << rigShown << endl;
deffile << rigX << endl;
deffile << rigY << endl;
deffile << RxTextHeight << endl;
deffile.close();
}
@ -77,6 +80,7 @@ void status::initLastState()
deffile >> rigShown;
deffile >> rigX;
deffile >> rigY;
deffile >> RxTextHeight;
deffile.close();
}
trx_mode m = (trx_mode) lastmode;
@ -119,6 +123,22 @@ void status::initLastState()
else
active_modem->set_freq(progdefaults.PSKsweetspot);
//std::cout << ReceiveText->h() << std::endl;
//std::cout << RxTextHeight << std::endl;
int X, Y, W, H, Yx, Hx;
X = ReceiveText->x();
Y = ReceiveText->y();
W = ReceiveText->w();
H = ReceiveText->h();
Yx = TransmitText->y();
Hx = TransmitText->h();
ReceiveText->resize(X,Y,W,RxTextHeight);
FHdisp->resize(X,Y,W,RxTextHeight);
TransmitText->resize(X, Y + RxTextHeight, W, H + Hx - RxTextHeight);
// TiledGroup->position( 0, ReceiveText->h(), 0, RxTextHeight);
fl_digi_main->resize(mainX, mainY, mainW, mainH);
if (rigShown == true) {
if (!rigcontrol)

Wyświetl plik

@ -283,6 +283,7 @@ void psk::searchUp()
void psk::afc()
{
double error, ftest, sigpwr, noise;
static int cntdown = 0;
if (mailserver && progdefaults.PSKmailSweetSpot)
ftest = wf->peakFreq((int)progdefaults.PSKsweetspot, (int) bandwidth);
else
@ -292,6 +293,7 @@ void psk::afc()
// fast search for peak signal frequency
if (sigsearch) {
freqerr = 0.0;
cntdown = 16;
if (sigpwr/noise > 2.0) {//afcthreshold) {
if (!mailserver || (mailserver && !progdefaults.PSKmailSweetSpot) ||
(mailserver && (fabs(progdefaults.PSKsweetspot - ftest) < 15))) {
@ -311,11 +313,14 @@ void psk::afc()
error += 2 * M_PI;
if (error > M_PI / 2)
error -= 2 * M_PI;
error *= ((samplerate / (symbollen * 2 * M_PI)/16));
freqerr = decayavg( freqerr, error, 8);//32);
if (cntdown > 0) cntdown--;
if (cntdown)
freqerr = decayavg( freqerr, error * ((samplerate / (symbollen * 2 * M_PI)/16)), 2);
else
freqerr = decayavg( freqerr, error * ((samplerate / (symbollen * 2 * M_PI)/16)), 16);
frequency -= freqerr;
set_freq (frequency);
//sprintf(phasemsg,"%5.4f %8.2f", freqerr, frequency);
//sprintf(phasemsg,"%5.4f %5.4f %8.2f", error, freqerr, frequency);
//put_status(phasemsg);
} else if (mailserver && progdefaults.PSKmailSweetSpot)
sigsearch = 3;
@ -323,8 +328,6 @@ void psk::afc()
void psk::rx_symbol(complex symbol)
{
// double phase, error;
// int bits, n;
int n;
phase = (prevsymbol % symbol).arg();
prevsymbol = symbol;

Wyświetl plik

@ -3,10 +3,13 @@
cSound::cSound(const char *dev ) {
device = dev;
capture = playback = generate = false;
tx_src_state = 0;
tx_src_data = 0;
rx_src_state = 0;
rx_src_data = 0;
cbuff = 0;
snd_buffer = 0;
src_buffer = 0;
txppm = progdefaults.TX_corr;
@ -24,46 +27,6 @@ cSound::cSound(const char *dev ) {
<< " <" << device.c_str()
<< ">" << std::endl;
}
try {
int err;
snd_buffer = new float [2*SND_BUF_LEN]; //new float[SND_BUF_LEN];
src_buffer = new float [2*SND_BUF_LEN]; //new float[SND_BUF_LEN];
cbuff = new unsigned char [4 * SND_BUF_LEN]; //new unsigned char [2 * SND_BUF_LEN];
if (!snd_buffer || !src_buffer || !cbuff)
throw("Cannot create src buffers");
// for (int i = 0; i < SND_BUF_LEN; i++)
for (int i = 0; i < 2*SND_BUF_LEN; i++)
snd_buffer[i] = src_buffer[i] = 0.0;
// for (int i = 0; i < 2 * SND_BUF_LEN; i++)
for (int i = 0; i < 4 * SND_BUF_LEN; i++)
cbuff[i] = 0;
tx_src_data = new SRC_DATA;
rx_src_data = new SRC_DATA;
if (!tx_src_data || !rx_src_data)
throw("Cannot create source data structures");
// rx_src_state = src_new(SRC_SINC_FASTEST, 1, &err);
rx_src_state = src_new(SRC_SINC_FASTEST, 2, &err);
if (rx_src_state == 0)
throw(src_strerror(err));
// tx_src_state = src_new(SRC_SINC_FASTEST, 1, &err);
tx_src_state = src_new(SRC_SINC_FASTEST, 2, &err);
if (tx_src_state == 0)
throw(src_strerror(err));
rx_src_data->src_ratio = 1.0/(1.0 + rxppm/1e6);
src_set_ratio ( rx_src_state, 1.0/(1.0 + rxppm/1e6));
tx_src_data->src_ratio = 1.0 + txppm/1e6;
src_set_ratio ( tx_src_state, 1.0 + txppm/1e6);
}
catch (SndException){
exit(1);
};
}
cSound::~cSound()
@ -76,6 +39,13 @@ cSound::~cSound()
if (rx_src_data) delete rx_src_data;
if (rx_src_state) src_delete (rx_src_state);
if (tx_src_state) src_delete (tx_src_state);
tx_src_state = 0;
tx_src_data = 0;
rx_src_state = 0;
rx_src_data = 0;
cbuff = 0;
snd_buffer = 0;
src_buffer = 0;
}
void cSound::setfragsize()
@ -95,7 +65,7 @@ void cSound::setfragsize()
throw errno;
}
int cSound::Open(int md, int freq)
int cSound::Open(int md, int freq, int nchan)
{
mode = md;
try {
@ -103,14 +73,57 @@ int cSound::Open(int md, int freq)
if (device_fd == -1)
throw SndException(errno);
Format(AFMT_S16_LE); // default: 16 bit little endian
// Channels(1); // 1 channel
Channels(2); // 2 channels
Frequency(freq);
Channels(nchan); // 2 channels is default
Frequency(freq); // 8000 Hz is default
setfragsize();
}
catch (...) {
throw;
}
if (cbuff) delete [] cbuff;
if (snd_buffer) delete [] snd_buffer;
if (src_buffer) delete [] src_buffer;
if (tx_src_data) delete tx_src_data;
if (rx_src_data) delete rx_src_data;
if (rx_src_state) src_delete (rx_src_state);
if (tx_src_state) src_delete (tx_src_state);
try {
int err;
snd_buffer = new float [channels * SND_BUF_LEN];
src_buffer = new float [channels * SND_BUF_LEN];
cbuff = new unsigned char [channels * 2 * SND_BUF_LEN];
if (!snd_buffer || !src_buffer || !cbuff)
throw("Cannot create src buffers");
for (int i = 0; i < channels * SND_BUF_LEN; i++)
snd_buffer[i] = src_buffer[i] = 0.0;
for (int i = 0; i < channels * 2 * SND_BUF_LEN; i++)
cbuff[i] = 0;
tx_src_data = new SRC_DATA;
rx_src_data = new SRC_DATA;
if (!tx_src_data || !rx_src_data)
throw("Cannot create source data structures");
rx_src_state = src_new(SRC_SINC_FASTEST, channels, &err);
if (rx_src_state == 0)
throw(src_strerror(err));
tx_src_state = src_new(SRC_SINC_FASTEST, channels, &err);
if (tx_src_state == 0)
throw(src_strerror(err));
rx_src_data->src_ratio = 1.0/(1.0 + rxppm/1e6);
src_set_ratio ( rx_src_state, 1.0/(1.0 + rxppm/1e6));
tx_src_data->src_ratio = 1.0 + txppm/1e6;
src_set_ratio ( tx_src_state, 1.0 + txppm/1e6);
}
catch (SndException){
exit(1);
};
return device_fd;
}
@ -256,7 +269,11 @@ int cSound::Read(double *buffer, int buffersize)
rx_src_data->src_ratio = 1.0/(1.0 + rxppm/1e6);
src_set_ratio ( rx_src_state, 1.0/(1.0 + rxppm/1e6));
}
if (rxppm == 0)
if (capture) writeCapture( buffer, buffersize);
else if (playback) readPlayback( buffer, buffersize);
if (rxppm == 0 || playback)
return buffersize;
// process using samplerate library
@ -285,6 +302,8 @@ int cSound::write_samples(double *buf, int count)
short int *wbuff;
unsigned char *p;
if (generate) writeGenerate( buf, count);
if (device_fd == -1 || count <= 0)
return -1;
@ -345,6 +364,8 @@ int cSound::write_stereo(double *bufleft, double *bufright, int count)
short int *wbuff;
unsigned char *p;
if (generate) writeGenerate( bufleft, count );
if (device_fd == -1 || count <= 0)
return -1;
@ -355,7 +376,6 @@ int cSound::write_stereo(double *bufleft, double *bufright, int count)
}
if (txppm == 0) {
wbuff = new short int[count];
wbuff = new short int[2*count];
p = (unsigned char *)wbuff;
for (int i = 0; i < count; i++) {
@ -403,3 +423,60 @@ int cSound::write_stereo(double *bufleft, double *bufright, int count)
return retval;
}
void cSound::Capture(bool on)
{
if (on)
ofCapture.open("capture.snd");
else
ofCapture.close();
capture = on;
}
void cSound::Playback(bool on)
{
// std::cout << "Playback " << on << endl;
if (on) {
ifPlayback.open("playback.snd", ios::in | ios::binary);
if (ifPlayback.is_open() == true)
playback = true;
return;
} else
ifPlayback.close();
playback = false;
}
void cSound::Generate(bool on)
{
if (on)
ofGenerate.open("generate.snd");
else
ofGenerate.close();
generate = on;
}
void cSound::writeGenerate(double *buff, int count)
{
char *cbuff = (char *)buff;
ofGenerate.write(cbuff, count * sizeof(double) );
}
void cSound::writeCapture(double *buff, int count)
{
char *cbuff = (char *)buff;
ofCapture.write(cbuff, count * sizeof(double) );
}
int cSound::readPlayback(double *buff, int count)
{
char *cbuff = (char *)buff;
if (ifPlayback.eof() == true) {
ifPlayback.close();
ifPlayback.open("playback.snd", ios::in | ios::binary);
}
ifPlayback.read(cbuff, count * sizeof(double) );
// std::cout << count << " " << ifPlayback.tellg() << endl;
return count;
}

Wyświetl plik

@ -973,54 +973,57 @@ bool waterfall::USB() {
waterfall::waterfall(int x0, int y0, int w0, int h0, char *lbl) :
Fl_Group(x0,y0,w0,h0,lbl) {
int xpos = x() + 4;
int xpos;
buttonrow = h() - BTN_HEIGHT + y();
buttonrow = h() + y() - BTN_HEIGHT - BEZEL;
bezel = new Fl_Box(
FL_DOWN_BOX,
x(),
y(),
w(),
h() - BTN_HEIGHT - 2, 0);
h() - BTN_HEIGHT - 2 * BEZEL, 0);
wfdisp = new WFdisp(x() + BEZEL,
y() + BEZEL,
w() - BEZEL - BEZEL,
h() - BEZEL - BEZEL - BTN_HEIGHT - 2);
w() - 2 * BEZEL,
h() - BTN_HEIGHT - 4 * BEZEL);
wfdisp->tooltip("Click to set tracking point");
xpos = x() + wSpace;
bwclr = new Fl_Button(xpos, buttonrow, bwColor, BTN_HEIGHT, "clr");
bwclr->callback(bwclr_cb, 0);
bwclr->tooltip("Color / BW waterfall");
xpos = xpos + bwColor + wSpace;
xpos = xpos + bwColor + wSpace;
mode = new Fl_Button(xpos, buttonrow, bwFFT, BTN_HEIGHT,"Wtr");
mode->callback(mode_cb, 0);
mode->tooltip("Waterfall/FFT - Shift click for signal scope");
xpos = xpos + bwFFT + wSpace;
xpos = xpos + bwFFT + wSpace;
x1 = new Fl_Button(xpos, buttonrow, bwX1, BTN_HEIGHT, "x1");
x1->callback(x1_cb, 0);
x1->tooltip("Change scale");
xpos = xpos + bwX1 + wSpace;
xpos = xpos + bwX1 + wSpace;
wfrate = new Fl_Button(xpos, buttonrow, bwRate, BTN_HEIGHT, "Norm");
wfrate->callback(rate_cb, 0);
wfrate->tooltip("Waterfall drop speed");
xpos = xpos + bwRate + 2*wSpace;
xpos = xpos + bwRate + wSpace;
left = new Fl_Repeat_Button(xpos, buttonrow, bwMov, BTN_HEIGHT, "@<");
left->callback(slew_left, 0);
left->tooltip("Slew display lower in freq");
xpos += bwMov;
center = new Fl_Button(xpos, buttonrow, bwMov, BTN_HEIGHT, "@||");
center->callback(center_cb, 0);
center->tooltip("Center display on signal");
xpos += bwMov;
right = new Fl_Repeat_Button(xpos, buttonrow, bwMov, BTN_HEIGHT, "@>");
right->callback(slew_right, 0);
right->tooltip("Slew display higher in freq");
xpos = xpos + bwMov + 2*wSpace;
xpos = xpos + bwMov + wSpace;
wfcarrier = new Fl_Counter(xpos, buttonrow, cwCnt, BTN_HEIGHT );
wfcarrier->callback(carrier_cb, 0);
wfcarrier->step(1.0);
@ -1029,8 +1032,8 @@ waterfall::waterfall(int x0, int y0, int w0, int h0, char *lbl) :
wfcarrier->range(16.0, IMAGE_WIDTH - 16.0);
wfcarrier->value(wfdisp->carrier());
wfcarrier->tooltip("Adjust selected tracking freq");
xpos = xpos + cwCnt + 2*wSpace;
xpos = xpos + cwCnt + wSpace;
wfRefLevel = new Fl_Counter(xpos, buttonrow, cwRef, BTN_HEIGHT );
wfRefLevel->callback(reflevel_cb, 0);
wfRefLevel->step(1.0);
@ -1040,8 +1043,8 @@ waterfall::waterfall(int x0, int y0, int w0, int h0, char *lbl) :
wfdisp->Reflevel(0.0);
wfRefLevel->tooltip("Upper signal limit in dB");
wfRefLevel->type(FL_SIMPLE_COUNTER);
xpos = xpos + cwRef + 2*wSpace;
xpos = xpos + cwRef + wSpace;
wfAmpSpan = new Fl_Counter(xpos, buttonrow, cwRef, BTN_HEIGHT );
wfAmpSpan->callback(ampspan_cb, 0);
wfAmpSpan->step(1.0);
@ -1052,26 +1055,25 @@ waterfall::waterfall(int x0, int y0, int w0, int h0, char *lbl) :
wfAmpSpan->tooltip("Signal range in dB");
wfAmpSpan->type(FL_SIMPLE_COUNTER);
xpos = xpos + cwRef + 2*wSpace;
xpos = xpos + cwRef + wSpace;
qsy = new Fl_Button(xpos, buttonrow, bwQsy, BTN_HEIGHT, "QSY");
qsy->callback(qsy_cb, 0);
qsy->tooltip("Cntr in Xcvr PB");
qsy->deactivate();
xpos = xpos + bwQsy + wSpace;
xmtlock = new Fl_Light_Button(xpos, buttonrow, bwXmtLock, BTN_HEIGHT, "Lck");
xmtlock = new Fl_Light_Button(xpos, buttonrow, bwXmtLock, BTN_HEIGHT, "Lk");
xmtlock->callback(xmtlock_cb, 0);
xmtlock->value(0);
xmtlock->tooltip("Xmt freq locked");
xpos = xpos + bwXmtLock + wSpace;
btnRev = new Fl_Light_Button(xpos, buttonrow, bwRev, BTN_HEIGHT, "Rev");
xpos = xpos + bwXmtLock + wSpace;
btnRev = new Fl_Light_Button(xpos, buttonrow, bwRev, BTN_HEIGHT, "Rv");
btnRev->callback(btnRev_cb, 0);
btnRev->value(0);
btnRev->tooltip("Reverse");
reverse = false;
xpos = w() - bwXmtRcv - wSpace;
xmtrcv = new Fl_Light_Button(xpos, buttonrow, bwXmtRcv, BTN_HEIGHT, "T/R");
xmtrcv->callback(xmtrcv_cb, 0);