kopia lustrzana https://github.com/jamescoxon/dl-fldigi
Upstream version 1.35N
rodzic
3be91c169f
commit
dcf89d5323
4
AUTHORS
4
AUTHORS
|
|
@ -1,3 +1,7 @@
|
|||
AUTHOR: Dave Freese
|
||||
CALLSIGN: W1HKJ
|
||||
EMAIL: w1hkj@w1hkj.com
|
||||
|
||||
AUTHOR: Stelios Bounanos
|
||||
CALLSIGN: M3RNV
|
||||
EMAIL:
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ 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) Corrected memory leak bugs found in version 1.34
|
||||
10) Added "Test" capability to save Rx or Tx waveforms in ".wav"
|
||||
format and to play them back for testing modem decoders.
|
||||
1.34 1) Cleaned up unused code segments
|
||||
2) Modified CW decoder to allow setting upper and lower limits on
|
||||
Tx WPM
|
||||
|
|
|
|||
46
INSTALL
46
INSTALL
|
|
@ -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.
|
||||
|
||||
8
README
8
README
|
|
@ -30,3 +30,11 @@ Hamlib Library Source the latest release is 1.2.6, download this release.
|
|||
Follow the instruction in the source code top directory. The library must
|
||||
be installed as super user. You should compile as your normal login user.
|
||||
The precompiled hamlib RPM and DEB distributions usually work OK.
|
||||
|
||||
3. PortAudio - you will need to build and install both libportaudio and
|
||||
libportaudiocpp. See website, www.portaudio.com
|
||||
|
||||
4. Sndfile - you will need to build and install libsndfile. See website,
|
||||
http://www.mega-nerd.com/libsndfile by Erik de Castro Lopo. Erik is also
|
||||
the author of the resampling library that is used in fldigi to compensate
|
||||
for the sound card offsets.
|
||||
|
|
|
|||
14
makefile
14
makefile
|
|
@ -120,21 +120,22 @@ endef
|
|||
|
||||
ifeq ($(CTARG),hamlib)
|
||||
CFLAGS = $(CCFLAGS) -DPORTAUDIO
|
||||
LDFLAGS = $(DYN_LDFLAGS) -lportaudiocpp
|
||||
LDFLAGS = $(DYN_LDFLAGS) -lportaudiocpp -lportaudio -lsndfile
|
||||
$(TARGET): print_header directories $(SRC_OBJS) $(HAMLIB_OBJS)
|
||||
$(CC) -s -o $(OUTPUT_DIR)/$(TARGET) $(SRC_OBJS) $(HAMLIB_OBJS) $(LDFLAGS) $(HAMLIBS)
|
||||
endif
|
||||
|
||||
ifeq ($(CTARG),hamlib-local)
|
||||
CFLAGS = $(CCFLAGS) -DPORTAUDIO
|
||||
LDFLAGS = $(STATIC_LDFLAGS) -lportaudiocpp
|
||||
LDFLAGS = $(STATIC_LDFLAGS) \
|
||||
/usr/local/lib/libportaudiocpp.a /usr/local/lib/libportaudio.a /usr/local/lib/libsndfile.a
|
||||
$(TARGET): print_header directories $(SRC_OBJS) $(HAMLIB_OBJS)
|
||||
$(CC) -s -o $(OUTPUT_DIR)/$(TARGET) $(SRC_OBJS) $(HAMLIB_OBJS) $(LDFLAGS) $(HAMLIBS) $(IMGLIBS)
|
||||
endif
|
||||
|
||||
ifeq ($(CTARG),hamlib-debug)
|
||||
CFLAGS = $(CCFLAGS) -g -DPORTAUDIO
|
||||
LDFLAGS = $(DYN_LDFLAGS) -lportaudiocpp
|
||||
LDFLAGS = $(DYN_LDFLAGS) -lportaudiocpp -lportaudio -lsndfile
|
||||
OBJS = $(SRC_OBJS) $(HAMLIB_OBJS)
|
||||
$(TARGET): print_header directories $(SRC_OBJS) $(HAMLIB_OBJS)
|
||||
$(CC) -o $(OUTPUT_DIR)/$(TARGET) $(OBJS) $(LDFLAGS) $(HAMLIBS)
|
||||
|
|
@ -142,21 +143,22 @@ endif
|
|||
|
||||
ifeq ($(CTARG),nhl)
|
||||
CFLAGS = $(CCFLAGS) -DNOHAMLIB -DPORTAUDIO
|
||||
LDFLAGS = $(DYN_LDFLAGS) -lportaudiocpp
|
||||
LDFLAGS = $(DYN_LDFLAGS) -lportaudiocpp -lportaudio -lsndfile
|
||||
$(TARGET): print_header directories $(SRC_OBJS)
|
||||
$(CC) -s -o $(OUTPUT_DIR)/$(TARGET) $(SRC_OBJS) $(LDFLAGS)
|
||||
endif
|
||||
|
||||
ifeq ($(CTARG),nhl-local)
|
||||
CFLAGS = $(CCFLAGS) -DNOHAMLIB -DPORTAUDIO
|
||||
LDFLAGS = $(STATIC_LDFLAGS) /usr/local/lib/libportaudiocpp.a /usr/local/lib/libportaudio.a
|
||||
LDFLAGS = $(STATIC_LDFLAGS) \
|
||||
/usr/local/lib/libportaudiocpp.a /usr/local/lib/libportaudio.a /usr/local/lib/libsndfile.a
|
||||
$(TARGET): print_header directories $(SRC_OBJS)
|
||||
$(CC) -s -o $(OUTPUT_DIR)/$(TARGET) $(SRC_OBJS) $(LDFLAGS) $(IMGLIBS)
|
||||
endif
|
||||
|
||||
ifeq ($(CTARG),nhl-debug)
|
||||
CFLAGS = $(CCFLAGS) -DNOHAMLIB -DPORTAUDIO -g
|
||||
LDFLAGS = $(DYN_LDFLAGS) -lportaudiocpp
|
||||
LDFLAGS = $(DYN_LDFLAGS) -lportaudiocpp -lportaudio -lsndfile
|
||||
$(TARGET): print_header directories $(SRC_OBJS)
|
||||
$(CC) -o $(OUTPUT_DIR)/$(TARGET) $(SRC_OBJS) $(LDFLAGS)
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -90,12 +90,13 @@ void rtty::init()
|
|||
|
||||
rtty::~rtty()
|
||||
{
|
||||
delete hilbert;
|
||||
if (hilbert) delete hilbert;
|
||||
if (wfid) delete wfid;
|
||||
if (bitfilt) delete bitfilt;
|
||||
// if (KeyLine) {
|
||||
// delete KeyLine;
|
||||
// KeyLine = (modeIO *)0;
|
||||
// }
|
||||
if (wfid) delete wfid;
|
||||
}
|
||||
|
||||
void rtty::restart()
|
||||
|
|
@ -198,6 +199,7 @@ void rtty::clear_syncscope()
|
|||
double *data = new double[symbollen];
|
||||
for (int i = 0; i < symbollen; data[i++] = 0.0);
|
||||
set_scope(data, symbollen, false);
|
||||
delete [] data;
|
||||
}
|
||||
|
||||
complex rtty::mixer(complex in)
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ void fftfilt::create_filter(double f1, double f2)
|
|||
tmpfft->cdft(filter);
|
||||
// start outputs after 2 full passes are complete
|
||||
pass = 2;
|
||||
delete tmpfft;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <glob.h>
|
||||
#include <FL/Fl_Double_Window.H>
|
||||
#include <FL/filename.H>
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
#include <math.h>
|
||||
|
||||
#include <string>
|
||||
#include <fstream.h>
|
||||
#include <iostream.h>
|
||||
#include <sndfile.hh>
|
||||
#include <iostream>
|
||||
|
||||
#ifdef PORTAUDIO
|
||||
#include <portaudiocpp/PortAudioCpp.hxx>
|
||||
|
|
@ -35,24 +35,29 @@
|
|||
|
||||
#define powerof2(n) ((((n) - 1) & (n)) == 0)
|
||||
|
||||
class SndException {
|
||||
class SndException : public std::exception
|
||||
{
|
||||
public:
|
||||
char szError[80];
|
||||
int error;
|
||||
SndException() { *szError = 0; error = 0; }
|
||||
SndException(int e) {
|
||||
sprintf(szError,"Error: %d, %s", e, strerror(e));
|
||||
snprintf(szError, sizeof(szError) - 1, "Error: %d, %s", e, strerror(e));
|
||||
error = e;
|
||||
}
|
||||
SndException(char *s) {
|
||||
sprintf(szError,"Error: %s", s);
|
||||
SndException(const char *s) {
|
||||
snprintf(szError, sizeof(szError) - 1, "Error: %s", s);
|
||||
error = 1;
|
||||
}
|
||||
const char *what(void) const throw() { return szError; }
|
||||
|
||||
private:
|
||||
char szError[80];
|
||||
int error;
|
||||
};
|
||||
|
||||
class cSound {
|
||||
|
||||
protected:
|
||||
int sample_frequency;
|
||||
int txppm;
|
||||
int rxppm;
|
||||
|
||||
|
|
@ -68,10 +73,10 @@ protected:
|
|||
bool playback;
|
||||
bool generate;
|
||||
|
||||
ofstream ofGenerate;
|
||||
ofstream ofCapture;
|
||||
fstream ifPlayback;
|
||||
|
||||
SndfileHandle* ofGenerate;
|
||||
SndfileHandle* ofCapture;
|
||||
SndfileHandle* ifPlayback;
|
||||
|
||||
void writeGenerate(double *buff, int count);
|
||||
void writeCapture(double *buff, int count);
|
||||
int readPlayback(double *buff, int count);
|
||||
|
|
@ -98,7 +103,6 @@ private:
|
|||
int format_mask;
|
||||
int channels;
|
||||
int play_format;
|
||||
int sample_frequency;
|
||||
int mode;
|
||||
bool formatok;
|
||||
unsigned char *cbuff;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef _VERSION_H
|
||||
#define _VERSION_H
|
||||
|
||||
#define FLDIGI_VERSION "1.35M"
|
||||
#define FLDIGI_VERSION "1.35N"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
66
src/main.cxx
66
src/main.cxx
|
|
@ -157,41 +157,43 @@ int main(int argc, char ** argv) {
|
|||
progdefaults.btnPTTREVis );
|
||||
|
||||
#ifndef PORTAUDIO
|
||||
scDevice = progdefaults.SCdevice;
|
||||
scDevice = progdefaults.SCdevice;
|
||||
#else
|
||||
if (progdefaults.btnAudioIOis == 0)
|
||||
scDevice = progdefaults.OSSdevice;
|
||||
else if (progdefaults.btnAudioIOis == 1)
|
||||
scDevice = progdefaults.PAdevice;
|
||||
if (progdefaults.btnAudioIOis == 0)
|
||||
scDevice = progdefaults.OSSdevice;
|
||||
else if (progdefaults.btnAudioIOis == 1)
|
||||
scDevice = progdefaults.PAdevice;
|
||||
#endif
|
||||
|
||||
glob_t gbuf;
|
||||
glob("/dev/dsp*", 0, NULL, &gbuf);
|
||||
for (size_t i = 0; i < gbuf.gl_pathc; i++)
|
||||
menuOSSDev->add(gbuf.gl_pathv[i]);
|
||||
glob_t gbuf;
|
||||
glob("/dev/dsp*", 0, NULL, &gbuf);
|
||||
for (size_t i = 0; i < gbuf.gl_pathc; i++)
|
||||
menuOSSDev->add(gbuf.gl_pathv[i]);
|
||||
globfree(&gbuf);
|
||||
|
||||
#ifdef PORTAUDIO
|
||||
portaudio::AutoSystem autoSys;
|
||||
portaudio::System &sys = portaudio::System::instance();
|
||||
for (portaudio::System::DeviceIterator idev = sys.devicesBegin();
|
||||
idev != sys.devicesEnd(); ++idev) {
|
||||
ostringstream o;
|
||||
string s;
|
||||
string::size_type i = 0;
|
||||
o << idev->index();
|
||||
s += o.str() + '-' + idev->name();
|
||||
while ((i = s.find('/', i)) != string::npos) {
|
||||
s.insert(i, 1, '\\');
|
||||
i += 2;
|
||||
}
|
||||
menuPADev->add(s.c_str());
|
||||
}
|
||||
btnAudioIO[1]->activate();
|
||||
portaudio::AutoSystem autoSys;
|
||||
portaudio::System &sys = portaudio::System::instance();
|
||||
for (portaudio::System::DeviceIterator idev = sys.devicesBegin();
|
||||
idev != sys.devicesEnd(); ++idev) {
|
||||
string s;
|
||||
s.append(idev->hostApi().name()).append("/").append(idev->name());
|
||||
string::size_type i = s.find('/') + 1;
|
||||
|
||||
// backslash-escape any slashes in the device name
|
||||
while ((i = s.find('/', i)) != string::npos) {
|
||||
s.insert(i, 1, '\\');
|
||||
i += 2;
|
||||
}
|
||||
menuPADev->add(s.c_str());
|
||||
}
|
||||
btnAudioIO[1]->activate();
|
||||
#endif
|
||||
|
||||
glob("/dev/mixer*", 0, NULL, &gbuf);
|
||||
for (size_t i = 0; i < gbuf.gl_pathc; i++)
|
||||
menuMix->add(gbuf.gl_pathv[i]);
|
||||
globfree(&gbuf);
|
||||
glob("/dev/mixer*", 0, NULL, &gbuf);
|
||||
for (size_t i = 0; i < gbuf.gl_pathc; i++)
|
||||
menuMix->add(gbuf.gl_pathv[i]);
|
||||
globfree(&gbuf);
|
||||
|
||||
if (progdefaults.MXdevice == "") {
|
||||
int n = 0;
|
||||
|
|
@ -201,12 +203,14 @@ int main(int argc, char ** argv) {
|
|||
menuMix->value(progdefaults.MXdevice.c_str());
|
||||
}
|
||||
|
||||
resetMixerControls();
|
||||
resetMixerControls();
|
||||
|
||||
trx_start(scDevice.c_str());
|
||||
|
||||
progdefaults.initInterface();
|
||||
|
||||
fl_digi_main->show();
|
||||
|
||||
progStatus.initLastState();
|
||||
wf->opmode();
|
||||
|
||||
|
|
@ -224,8 +228,6 @@ int main(int argc, char ** argv) {
|
|||
Fl::add_timeout(10.0, pskmail_loop);
|
||||
}
|
||||
|
||||
fl_digi_main->show();
|
||||
|
||||
return Fl::run();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ configuration progdefaults = {
|
|||
0, // int btnAudioIOis
|
||||
"/dev/dsp", // string SCdevice;
|
||||
"/dev/dsp", // string OSSdevice;
|
||||
"0-/dev/dsp", // string PAdevice;
|
||||
"/dev/dsp", // string PAdevice;
|
||||
0, // int RX_corr;
|
||||
0, // int TX_corr;
|
||||
0, // int TxOffset;
|
||||
|
|
@ -274,7 +274,7 @@ void configuration::writeDefaultsXML()
|
|||
|
||||
writeXMLstr(f, "PTTDEV", PTTdev);
|
||||
writeXMLstr(f, "SECONDARYTEXT", secText);
|
||||
writeXMLint(f, "AUDIOIO", btnAudioIOis);
|
||||
writeXMLint(f, "AUDIOIO", btnAudioIOis);
|
||||
writeXMLstr(f, "SCDEVICE", SCdevice);
|
||||
writeXMLstr(f, "OSSDEVICE", OSSdevice);
|
||||
writeXMLstr(f, "PADEVICE", PAdevice);
|
||||
|
|
@ -537,7 +537,7 @@ void configuration::readDefaults(ifstream &f)
|
|||
f >> MXdevice;
|
||||
f >> btnAudioIOis;
|
||||
f >> OSSdevice;
|
||||
f >> PAdevice;
|
||||
getline(f >> ws, PAdevice);
|
||||
}
|
||||
|
||||
void configuration::loadDefaults() {
|
||||
|
|
|
|||
|
|
@ -250,21 +250,19 @@ int MACROTEXT::loadMacros(string filename)
|
|||
char szTemp[10];
|
||||
char szLine[255];
|
||||
|
||||
ifstream *mFile;
|
||||
|
||||
mFile = new ifstream(filename.c_str());
|
||||
ifstream mFile(filename.c_str());
|
||||
|
||||
if (!mFile->is_open()) {
|
||||
if (!mFile) {
|
||||
createDotFldigi();
|
||||
mFile = new ifstream(filename.c_str());
|
||||
if (!mFile->is_open())
|
||||
mFile.open(filename.c_str());
|
||||
if (!mFile)
|
||||
return -1;
|
||||
}
|
||||
|
||||
mFile->getline(szLine, 255);
|
||||
mFile.getline(szLine, 255);
|
||||
mLine = szLine;
|
||||
if (mLine.find("//fldigi macro definition file") != 0) {
|
||||
mFile->close();
|
||||
mFile.close();
|
||||
return -1;
|
||||
}
|
||||
// clear all of the macros
|
||||
|
|
@ -275,8 +273,8 @@ int MACROTEXT::loadMacros(string filename)
|
|||
text[i] = "";
|
||||
}
|
||||
inMacro = false;
|
||||
while (!mFile->eof()) {
|
||||
mFile->getline(szLine,255);
|
||||
while (!mFile.eof()) {
|
||||
mFile.getline(szLine,255);
|
||||
mLine = szLine;
|
||||
if (mLine.find("//") == 0) // skip over all comment lines
|
||||
continue;
|
||||
|
|
@ -299,7 +297,7 @@ int MACROTEXT::loadMacros(string filename)
|
|||
}
|
||||
text[mNumber] = text[mNumber] + mLine;
|
||||
}
|
||||
mFile->close();
|
||||
mFile.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -159,8 +159,8 @@ psk::psk(trx_mode pskmode) : modem()
|
|||
dec = (viterbi *)0;
|
||||
|
||||
// create impulse response for experimental FIR filters
|
||||
fir1c = new double[64];
|
||||
fir2c = new double[64];
|
||||
double fir1c[64];
|
||||
double fir2c[64];
|
||||
|
||||
// raisedcosfilt(fir1c); // creates fir1c
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
#include "sound.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#ifdef MAX
|
||||
#undef MAX
|
||||
#endif
|
||||
|
||||
#ifdef MIN
|
||||
#undef MIN
|
||||
#endif
|
||||
#ifdef MAX
|
||||
#undef MAX
|
||||
#endif
|
||||
|
||||
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
|
|
@ -15,10 +14,9 @@
|
|||
cSound::cSound()
|
||||
: txppm(progdefaults.TX_corr), rxppm(progdefaults.RX_corr),
|
||||
tx_src_state(0), tx_src_data(0), rx_src_state(0), rx_src_data(0),
|
||||
snd_buffer(0), src_buffer(0)
|
||||
{
|
||||
capture = playback = generate = false;
|
||||
}
|
||||
snd_buffer(0), src_buffer(0), capture(false), playback(false),
|
||||
generate(false), ofGenerate(0), ofCapture(0), ifPlayback(0)
|
||||
{ }
|
||||
|
||||
cSound::~cSound()
|
||||
{
|
||||
|
|
@ -28,60 +26,99 @@ 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);
|
||||
delete ofGenerate;
|
||||
delete ofCapture;
|
||||
delete ifPlayback;
|
||||
}
|
||||
|
||||
void cSound::Capture(bool on)
|
||||
{
|
||||
if (on)
|
||||
ofCapture.open("capture.snd");
|
||||
else
|
||||
ofCapture.close();
|
||||
if (on) {
|
||||
ofCapture = new SndfileHandle("capture.wav", SFM_WRITE,
|
||||
SF_FORMAT_WAV | SF_FORMAT_PCM_16,
|
||||
1, sample_frequency);
|
||||
if (!*ofCapture) {
|
||||
cerr << "Could not write capture.wav" << endl;
|
||||
delete ofCapture;
|
||||
ofCapture = 0;
|
||||
return;
|
||||
}
|
||||
// cerr << "Opened capture.wav" << endl;
|
||||
ofCapture->command(SFC_SET_UPDATE_HEADER_AUTO, 0, SF_TRUE);
|
||||
}
|
||||
else {
|
||||
delete ofCapture;
|
||||
ofCapture = 0;
|
||||
// cerr << "Closed capture.wav" << endl;
|
||||
}
|
||||
|
||||
capture = on;
|
||||
}
|
||||
|
||||
void cSound::Playback(bool on)
|
||||
{
|
||||
if (on) {
|
||||
ifPlayback.open("playback.snd", ios::in | ios::binary);
|
||||
if (ifPlayback.is_open() == true)
|
||||
playback = true;
|
||||
return;
|
||||
} else
|
||||
ifPlayback.close();
|
||||
playback = false;
|
||||
ifPlayback = new SndfileHandle("playback.wav");
|
||||
if (!*ifPlayback) {
|
||||
cerr << "Could not read playback.wav" << endl;
|
||||
delete ifPlayback;
|
||||
ifPlayback = 0;
|
||||
return;
|
||||
}
|
||||
playback = true;
|
||||
}
|
||||
else {
|
||||
delete ifPlayback;
|
||||
ifPlayback = 0;
|
||||
playback = false;
|
||||
}
|
||||
}
|
||||
|
||||
void cSound::Generate(bool on)
|
||||
{
|
||||
if (on)
|
||||
ofGenerate.open("generate.snd");
|
||||
else
|
||||
ofGenerate.close();
|
||||
if (on) {
|
||||
cerr << "opening generate.wav" << endl;
|
||||
ofGenerate = new SndfileHandle("generate.wav", SFM_WRITE,
|
||||
SF_FORMAT_WAV | SF_FORMAT_PCM_16,
|
||||
1, sample_frequency);
|
||||
if (!*ofGenerate) {
|
||||
cerr << "Could not write generate.wav" << endl;
|
||||
delete ofGenerate;
|
||||
ofGenerate = 0;
|
||||
return;
|
||||
}
|
||||
ofGenerate->command(SFC_SET_UPDATE_HEADER_AUTO, 0, SF_TRUE);
|
||||
}
|
||||
else {
|
||||
delete ofGenerate;
|
||||
ofGenerate = 0;
|
||||
}
|
||||
|
||||
generate = on;
|
||||
}
|
||||
|
||||
void cSound::writeGenerate(double *buff, int count)
|
||||
{
|
||||
char *cbuff = (char *)buff;
|
||||
ofGenerate.write(cbuff, count * sizeof(double) );
|
||||
ofGenerate->writef(buff, count);
|
||||
}
|
||||
|
||||
void cSound::writeCapture(double *buff, int count)
|
||||
{
|
||||
char *cbuff = (char *)buff;
|
||||
ofCapture.write(cbuff, count * sizeof(double) );
|
||||
ofCapture->writef(buff, count);
|
||||
}
|
||||
|
||||
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) );
|
||||
sf_count_t r = ifPlayback->readf(buff, count);
|
||||
|
||||
return count;
|
||||
while (r < count) {
|
||||
ifPlayback->seek(0, SEEK_SET);
|
||||
r += ifPlayback->readf(buff + r, count - r);
|
||||
if (r == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -97,7 +134,7 @@ cSoundOSS::cSoundOSS(const char *dev ) {
|
|||
Close();
|
||||
}
|
||||
catch (SndException e) {
|
||||
std::cout << e.szError - 1
|
||||
std::cout << e.what()
|
||||
<< " <" << device.c_str()
|
||||
<< ">" << std::endl;
|
||||
}
|
||||
|
|
@ -491,13 +528,13 @@ cSoundPA::cSoundPA(const char *dev)
|
|||
rx_src_data = new SRC_DATA;
|
||||
tx_src_data = new SRC_DATA;
|
||||
if (!rx_src_data || !tx_src_data)
|
||||
throw("Cannot create source data structures");
|
||||
throw(SndException("Cannot create source data structures"));
|
||||
|
||||
snd_buffer = new float[2 * SND_BUF_LEN];
|
||||
src_buffer = new float[2 * SND_BUF_LEN];
|
||||
fbuf = new float[2 * SND_BUF_LEN];
|
||||
if (!snd_buffer || !src_buffer || !fbuf)
|
||||
throw("could not allocate buffers");
|
||||
throw(SndException("could not allocate buffers"));
|
||||
memset(snd_buffer, 0, 2 * SND_BUF_LEN);
|
||||
memset(src_buffer, 0, 2 * SND_BUF_LEN);
|
||||
memset(fbuf, 0, 2 * SND_BUF_LEN);
|
||||
|
|
@ -513,9 +550,21 @@ int cSoundPA::Open(int mode, int freq)
|
|||
{
|
||||
open_mode = mode;
|
||||
req_sample_rate = freq;
|
||||
sample_frequency = (int)req_sample_rate;
|
||||
|
||||
Close();
|
||||
init_stream();
|
||||
try {
|
||||
init_stream();
|
||||
}
|
||||
catch (const exception &e) {
|
||||
cerr << e.what() << endl;
|
||||
// make sure the stream is closed
|
||||
try {
|
||||
stream.close();
|
||||
}
|
||||
catch (...) { }
|
||||
throw(SndException(e.what()));
|
||||
}
|
||||
|
||||
int err;
|
||||
if (mode == O_RDONLY) {
|
||||
|
|
@ -524,7 +573,7 @@ int cSoundPA::Open(int mode, int freq)
|
|||
src_delete(rx_src_state);
|
||||
rx_src_state = src_new(SRC_SINC_FASTEST, 2, &err);
|
||||
if (!rx_src_state)
|
||||
throw(src_strerror(err));
|
||||
throw(SndException(src_strerror(err)));
|
||||
rx_src_data->src_ratio = req_sample_rate / (dev_sample_rate * (1.0 + rxppm / 1e6));
|
||||
}
|
||||
else if (mode == O_WRONLY) {
|
||||
|
|
@ -533,15 +582,15 @@ int cSoundPA::Open(int mode, int freq)
|
|||
src_delete(tx_src_state);
|
||||
tx_src_state = src_new(SRC_SINC_FASTEST, 2, &err);
|
||||
if (!tx_src_state)
|
||||
throw(src_strerror(err));
|
||||
throw(SndException(src_strerror(err)));
|
||||
tx_src_data->src_ratio = dev_sample_rate * (1.0 + txppm / 1e6) / req_sample_rate;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
||||
if (dev_sample_rate != req_sample_rate)
|
||||
cerr << "PA_debug: resampling " << dev_sample_rate
|
||||
<< " <-> " << req_sample_rate << endl;
|
||||
// if (dev_sample_rate != req_sample_rate)
|
||||
// cerr << "PA_debug: resampling " << dev_sample_rate
|
||||
// << " <-> " << req_sample_rate << endl;
|
||||
|
||||
stream.open(stream_params);
|
||||
stream.start();
|
||||
|
|
@ -559,16 +608,18 @@ void cSoundPA::Close(void)
|
|||
|
||||
int cSoundPA::Read(double *buf, int count)
|
||||
{
|
||||
int ncount = (int)floor(MIN(count, SND_BUF_LEN) / rx_src_data->src_ratio);
|
||||
int ncount = (int)floor(MIN(count, SND_BUF_LEN) / rx_src_data->src_ratio);
|
||||
|
||||
try {
|
||||
stream.read(fbuf, ncount);
|
||||
}
|
||||
catch (const portaudio::PaException &e) {
|
||||
cerr << e.what() << endl;
|
||||
if (strstr(e.what(), "rflow"))
|
||||
adjust_stream();
|
||||
}
|
||||
try {
|
||||
stream.read(fbuf, ncount);
|
||||
}
|
||||
catch (const portaudio::PaException &e) {
|
||||
cerr << e.what() << endl;
|
||||
if (strstr(e.what(), "rflow"))
|
||||
adjust_stream();
|
||||
else
|
||||
throw(SndException(e.what()));
|
||||
}
|
||||
|
||||
if (capture) writeCapture( buf, count);
|
||||
|
||||
|
|
@ -577,18 +628,18 @@ int cSoundPA::Read(double *buf, int count)
|
|||
return count;
|
||||
}
|
||||
|
||||
float *rbuf = fbuf;
|
||||
|
||||
if (req_sample_rate != dev_sample_rate || rxppm != progdefaults.RX_corr) {
|
||||
resample(rbuf, ncount, count);
|
||||
rbuf = rx_src_data->data_out;
|
||||
count = rx_src_data->output_frames_gen;
|
||||
}
|
||||
float *rbuf = fbuf;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
buf[i] = rbuf[2*i];
|
||||
if (req_sample_rate != dev_sample_rate || rxppm != progdefaults.RX_corr) {
|
||||
resample(rbuf, ncount, count);
|
||||
rbuf = rx_src_data->data_out;
|
||||
count = rx_src_data->output_frames_gen;
|
||||
}
|
||||
|
||||
return count;
|
||||
for (int i = 0; i < count; i++)
|
||||
buf[i] = rbuf[2*i];
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int cSoundPA::write_samples(double *buf, int count)
|
||||
|
|
@ -611,6 +662,8 @@ int cSoundPA::write_samples(double *buf, int count)
|
|||
cerr << e.what() << endl;
|
||||
if (strstr(e.what(), "rflow"))
|
||||
adjust_stream();
|
||||
else
|
||||
throw SndException(e.what());
|
||||
}
|
||||
|
||||
return count;
|
||||
|
|
@ -638,6 +691,8 @@ int cSoundPA::write_stereo(double *bufleft, double *bufright, int count)
|
|||
cerr << e.what() << endl;
|
||||
if (strstr(e.what(), "rflow"))
|
||||
adjust_stream();
|
||||
else
|
||||
throw SndException(e.what());
|
||||
}
|
||||
|
||||
return count;
|
||||
|
|
@ -683,26 +738,21 @@ void cSoundPA::resample(float *buf, int count, int max)
|
|||
|
||||
void cSoundPA::init_stream(void)
|
||||
{
|
||||
PaDeviceIndex ndev;
|
||||
istringstream ist(device);
|
||||
|
||||
if (!(ist >> ndev))
|
||||
ndev = 0;
|
||||
|
||||
bool found = false;
|
||||
|
||||
portaudio::System::DeviceIterator idev;
|
||||
for (idev = sys.devicesBegin(); idev != sys.devicesEnd(); ++idev) {
|
||||
if (idev->index() == ndev) {
|
||||
if (device == idev->name()) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
idev = sys.devicesBegin();
|
||||
cerr << "PA_debug: could not find device " << ndev << endl;
|
||||
cerr << "PA_debug: could not find device \"" << device << '"' << endl;
|
||||
}
|
||||
cerr << "PA_debug: using device " << idev->index() << " \""
|
||||
<< idev->name() << '"' << endl;
|
||||
// cerr << "PA_debug: using device " << idev->index() << " \""
|
||||
// << idev->name() << '"' << endl;
|
||||
|
||||
in_params.setDevice(*idev);
|
||||
in_params.setNumChannels(2);
|
||||
|
|
@ -726,7 +776,7 @@ void cSoundPA::init_stream(void)
|
|||
max_frames_per_buffer = ceil2(MIN(SND_BUF_LEN, (unsigned)(SCBLOCKSIZE *
|
||||
dev_sample_rate / req_sample_rate)));
|
||||
stream_params.setFramesPerBuffer(frames_per_buffer);
|
||||
cerr << "PA_debug: max_frames_per_buffer = " << max_frames_per_buffer << endl;
|
||||
// cerr << "PA_debug: max_frames_per_buffer = " << max_frames_per_buffer << endl;
|
||||
}
|
||||
|
||||
void cSoundPA::adjust_stream(void)
|
||||
|
|
@ -769,12 +819,12 @@ double cSoundPA::get_best_srate(void)
|
|||
portaudio::StreamParameters sp(in_params, out_params,
|
||||
std_sample_rates[i],
|
||||
0, paNoFlag);
|
||||
cerr << "PA_debug: trying " << std_sample_rates[i] << " Hz" << endl;
|
||||
// cerr << "PA_debug: trying " << std_sample_rates[i] << " Hz" << endl;
|
||||
if (sp.isSupported())
|
||||
return sp.sampleRate();
|
||||
}
|
||||
|
||||
throw("could not find a supported sample rate");
|
||||
throw(SndException("Could not find a supported sample rate. Sound device busy?"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ void throb::reset_syms() //call when switching from TX to RX or vice versa
|
|||
throb::throb(trx_mode throb_mode) : modem()
|
||||
{
|
||||
double bw;
|
||||
double *fp;
|
||||
double *fp = 0;
|
||||
|
||||
mode = throb_mode;
|
||||
|
||||
|
|
@ -217,6 +217,7 @@ throb::throb(trx_mode throb_mode) : modem()
|
|||
|
||||
syncfilt = new C_FIR_filter();
|
||||
syncfilt->init(symlen / DOWN_SAMPLE, 1, fp, NULL);
|
||||
delete fp;
|
||||
|
||||
snfilter = new Cmovavg(16);
|
||||
|
||||
|
|
|
|||
|
|
@ -163,8 +163,8 @@ void trx_tune_loop()
|
|||
} else
|
||||
xmttune::tune(active_modem->get_txfreq_woffset(), scard);
|
||||
}
|
||||
scard->Close();
|
||||
xmttune::keyup(active_modem->get_txfreq_woffset(), scard);
|
||||
scard->Close();
|
||||
_trx_tune = 0;
|
||||
} else
|
||||
MilliSleep(10);
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ Raster::Raster (int X, int Y, int W, int H) :
|
|||
height = H - 4;
|
||||
space = 2;
|
||||
rowheight = 60;
|
||||
Nrows = (int)(height / (rowheight + space) - 0.5);
|
||||
Nrows = height / (rowheight + space);
|
||||
vidbuf = new unsigned char[width * height];
|
||||
memset(vidbuf, 255, width * height);
|
||||
col = 0;
|
||||
|
|
@ -69,7 +69,7 @@ void Raster::data(int data[], int len)
|
|||
col++;
|
||||
if (col >= width) {
|
||||
unsigned char *from = vidbuf + (space + rowheight) * width;
|
||||
int numtocopy = Nrows * (space + rowheight) * width;
|
||||
int numtocopy = (Nrows-1) * (space + rowheight) * width;
|
||||
memmove(vidbuf, from, numtocopy);
|
||||
memset( vidbuf + yp * width,
|
||||
255, (space + rowheight) * width);
|
||||
|
|
@ -90,8 +90,6 @@ void Raster::data(int data[], int len)
|
|||
|
||||
redraw();
|
||||
Fl::unlock();
|
||||
|
||||
// redraw();
|
||||
Fl::awake();
|
||||
}
|
||||
|
||||
|
|
@ -103,14 +101,13 @@ void Raster::clear()
|
|||
col = width;
|
||||
redraw();
|
||||
Fl::unlock();
|
||||
// redraw();
|
||||
Fl::awake();
|
||||
}
|
||||
|
||||
void Raster::resize(int x, int y, int w, int h)
|
||||
{
|
||||
int Wdest = w - 4, Hdest = h - 4;
|
||||
int Ndest = (int)(Hdest / (rowheight + space) - 0.5);
|
||||
int Ndest = Hdest / (rowheight + space);
|
||||
unsigned char *tempbuf = new unsigned char [Wdest * Hdest];
|
||||
unsigned char *oldbuf;
|
||||
int xfrcols, xfrrows;
|
||||
|
|
@ -124,14 +121,14 @@ void Raster::resize(int x, int y, int w, int h)
|
|||
xfrcols = Wdest;
|
||||
|
||||
if (Ndest <= Nrows) {
|
||||
xfrrows = (Ndest + 1)*(rowheight + space);
|
||||
xfrrows = Ndest * (rowheight + space);
|
||||
from = (Nrows - Ndest) * (rowheight + space);
|
||||
to = 0;
|
||||
for (int r = 0; r < xfrrows; r++)
|
||||
for (int c = 0; c < xfrcols; c++)
|
||||
tempbuf[(to + r) * Wdest + c] = vidbuf[(from + r) * width + c];
|
||||
} else {
|
||||
xfrrows = (Nrows + 1)*(rowheight + space);
|
||||
xfrrows = Nrows * (rowheight + space);
|
||||
from = 0;
|
||||
to = (Ndest - Nrows) * (rowheight + space);
|
||||
for (int r = 0; r < xfrrows; r++)
|
||||
|
|
@ -156,8 +153,8 @@ void Raster::draw()
|
|||
{
|
||||
if ((damage() & FL_DAMAGE_USER2)) {
|
||||
draw_box();
|
||||
fl_draw_image_mono(
|
||||
vidbuf,
|
||||
fl_draw_image_mono(
|
||||
vidbuf,
|
||||
x() + 2, y() + 2,
|
||||
width, height,
|
||||
1, width );
|
||||
|
|
@ -170,11 +167,11 @@ void Raster::draw()
|
|||
numcols = 0;
|
||||
} else {
|
||||
draw_box();
|
||||
fl_draw_image_mono(
|
||||
vidbuf,
|
||||
fl_draw_image_mono(
|
||||
vidbuf,
|
||||
x() + 2, y() + 2,
|
||||
width, height,
|
||||
1, width );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,180 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// raster.cxx, Raster scan Widget for display of fuzzy modes
|
||||
//
|
||||
// Copyright (C) 2006
|
||||
// Dave Freese, W1HKJ
|
||||
//
|
||||
// This file is part of fldigi.
|
||||
//
|
||||
// fldigi is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// fldigi is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with fldigi; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "raster.h"
|
||||
#include "modem.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "raster.h"
|
||||
|
||||
bool rowschanged = false;
|
||||
|
||||
Raster::Raster (int X, int Y, int W, int H) :
|
||||
Fl_Widget (X, Y, W, H) {
|
||||
width = W - 4;
|
||||
height = H - 4;
|
||||
space = 2;
|
||||
rowheight = 60;
|
||||
Nrows = (int)(height / (rowheight + space) - 0.5);
|
||||
vidbuf = new unsigned char[width * height];
|
||||
memset(vidbuf, 255, width * height);
|
||||
col = 0;
|
||||
vidpos = 0;
|
||||
numcols = 0;
|
||||
yp = Nrows * (space + rowheight);
|
||||
box(FL_DOWN_BOX);
|
||||
}
|
||||
|
||||
Raster::~Raster()
|
||||
{
|
||||
delete [] vidbuf;
|
||||
}
|
||||
|
||||
|
||||
void Raster::data(int data[], int len)
|
||||
{
|
||||
if (data == NULL || len == 0)
|
||||
return;
|
||||
int h = len;
|
||||
int pos;
|
||||
int zeropos;
|
||||
|
||||
Fl::lock();
|
||||
|
||||
if (h > height)
|
||||
h = height;
|
||||
col++;
|
||||
if (col >= width) {
|
||||
unsigned char *from = vidbuf + (space + rowheight) * width;
|
||||
int numtocopy = Nrows * (space + rowheight) * width;
|
||||
memmove(vidbuf, from, numtocopy);
|
||||
memset( vidbuf + yp * width,
|
||||
255, (space + rowheight) * width);
|
||||
col = 0;
|
||||
damage(FL_DAMAGE_USER2);
|
||||
}
|
||||
else
|
||||
if (damage() != FL_DAMAGE_ALL)
|
||||
damage(FL_DAMAGE_USER1);
|
||||
zeropos = Nrows * (space + rowheight) * width;
|
||||
for (int i = 0; i < h; i++) {
|
||||
pos = zeropos + width * (h - i - 1) + col;
|
||||
vidbuf[pos] = (unsigned char)data[i];
|
||||
}
|
||||
numcols++;
|
||||
vidpos = col - numcols;
|
||||
if (vidpos < 0) vidpos = 0;
|
||||
|
||||
redraw();
|
||||
Fl::unlock();
|
||||
|
||||
// redraw();
|
||||
Fl::awake();
|
||||
}
|
||||
|
||||
void Raster::clear()
|
||||
{
|
||||
Fl::lock();
|
||||
for (int i = 0; i < width * height; i++)
|
||||
vidbuf[i] = 255;
|
||||
col = width;
|
||||
redraw();
|
||||
Fl::unlock();
|
||||
// redraw();
|
||||
Fl::awake();
|
||||
}
|
||||
|
||||
void Raster::resize(int x, int y, int w, int h)
|
||||
{
|
||||
int Wdest = w - 4, Hdest = h - 4;
|
||||
int Ndest = (int)(Hdest / (rowheight + space) - 0.5);
|
||||
unsigned char *tempbuf = new unsigned char [Wdest * Hdest];
|
||||
unsigned char *oldbuf;
|
||||
int xfrcols, xfrrows;
|
||||
int from, to;
|
||||
|
||||
memset(tempbuf, 255, Wdest * Hdest);
|
||||
|
||||
if (Wdest >= width)
|
||||
xfrcols = width;
|
||||
else
|
||||
xfrcols = Wdest;
|
||||
|
||||
if (Ndest <= Nrows) {
|
||||
xfrrows = (Ndest + 1)*(rowheight + space);
|
||||
from = (Nrows - Ndest) * (rowheight + space);
|
||||
to = 0;
|
||||
for (int r = 0; r < xfrrows; r++)
|
||||
for (int c = 0; c < xfrcols; c++)
|
||||
tempbuf[(to + r) * Wdest + c] = vidbuf[(from + r) * width + c];
|
||||
} else {
|
||||
xfrrows = (Nrows + 1)*(rowheight + space);
|
||||
from = 0;
|
||||
to = (Ndest - Nrows) * (rowheight + space);
|
||||
for (int r = 0; r < xfrrows; r++)
|
||||
for (int c = 0; c < xfrcols; c++)
|
||||
tempbuf[(to + r) * Wdest + c] = vidbuf[(from + r) * width + c];
|
||||
}
|
||||
|
||||
oldbuf = vidbuf;
|
||||
vidbuf = tempbuf;
|
||||
|
||||
width = Wdest; height = Hdest;
|
||||
Nrows = Ndest;
|
||||
yp = Ndest * (space + rowheight);
|
||||
|
||||
delete [] oldbuf;
|
||||
|
||||
Fl_Widget::resize(x,y,w,h);
|
||||
redraw();
|
||||
}
|
||||
|
||||
void Raster::draw()
|
||||
{
|
||||
if ((damage() & FL_DAMAGE_USER2)) {
|
||||
draw_box();
|
||||
fl_draw_image_mono(
|
||||
vidbuf,
|
||||
x() + 2, y() + 2,
|
||||
width, height,
|
||||
1, width );
|
||||
} else if ((damage() & FL_DAMAGE_USER1)) {
|
||||
fl_draw_image_mono(
|
||||
vidbuf + vidpos + Nrows * (space + rowheight) * width,
|
||||
x() + vidpos + 2, y() + yp + 2,
|
||||
numcols, rowheight,
|
||||
1, width);
|
||||
numcols = 0;
|
||||
} else {
|
||||
draw_box();
|
||||
fl_draw_image_mono(
|
||||
vidbuf,
|
||||
x() + 2, y() + 2,
|
||||
width, height,
|
||||
1, width );
|
||||
}
|
||||
}
|
||||
|
||||
Ładowanie…
Reference in New Issue