Merged master 8748
This commit is contained in:
@@ -1,207 +0,0 @@
|
||||
/*
|
||||
File name: wsprsim.c (first committed to wsjtx June 13, 2015)
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "wsprsim_utils.h"
|
||||
#include "wsprd_utils.h"
|
||||
#include "fano.h"
|
||||
|
||||
int printdata=0;
|
||||
|
||||
void usage() {
|
||||
printf("Usage: wsprsim [options] message\n");
|
||||
printf(" message format: \"K1ABC FN42 33\"\n");
|
||||
printf(" \"PJ4/K1ABC 33\"\n");
|
||||
printf(" \"<PJ4/K1ABC> FK52UD 33\"\n");
|
||||
printf("Options:\n");
|
||||
printf(" -c (print channel symbols)\n");
|
||||
printf(" -d (print packed data with zero tail - 11 bytes)\n");
|
||||
printf(" -o filename (write a c2 file with this name)\n");
|
||||
printf(" -s x (x is snr of signal that is written to .c2 file)\n");
|
||||
printf("\n");
|
||||
printf(" e.g. ./wsprsim -cds -28 -o 150613_1920.c2 \"K1ABC FN42 33\"\n");
|
||||
printf(" then ./wsprd 150613_1920.c2\n");
|
||||
}
|
||||
|
||||
int add_signal_vector(float f0, float t0, float amp, unsigned char* symbols
|
||||
, double* isig, double* qsig)
|
||||
{
|
||||
int i, j, ii, idelay;
|
||||
double phi=0.0, twopidt, df, dt, dphi;
|
||||
twopidt=8.0*atan(1.0)/375.0;
|
||||
df=375.0/256.0;
|
||||
dt=1/375.0;
|
||||
idelay=t0/dt;
|
||||
|
||||
for (i=0; i<162; i++) {
|
||||
dphi=twopidt*(f0 + ( (double)symbols[i]-1.5)*df );
|
||||
for ( j=0; j<256; j++ ) {
|
||||
ii=idelay+256*i+j;
|
||||
isig[ii]=isig[ii]+amp*cos(phi);
|
||||
qsig[ii]=qsig[ii]+amp*sin(phi);
|
||||
phi=phi+dphi;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
char* tobinary(int x)
|
||||
{
|
||||
static char b[33];
|
||||
b[0] = '\0';
|
||||
|
||||
long unsigned int z;
|
||||
for (z = 0x80000000; z > 0; z >>= 1)
|
||||
{
|
||||
strcat(b, ((x & z) == z) ? "1" : "0");
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
double gaussrand()
|
||||
{
|
||||
static double V1, V2, S;
|
||||
static int phase = 0;
|
||||
double X;
|
||||
|
||||
if(phase == 0) {
|
||||
do {
|
||||
double U1 = (double)rand() / RAND_MAX;
|
||||
double U2 = (double)rand() / RAND_MAX;
|
||||
|
||||
V1 = 2 * U1 - 1;
|
||||
V2 = 2 * U2 - 1;
|
||||
S = V1 * V1 + V2 * V2;
|
||||
} while(S >= 1 || S == 0);
|
||||
|
||||
X = V1 * sqrt(-2 * log(S) / S);
|
||||
} else
|
||||
X = V2 * sqrt(-2 * log(S) / S);
|
||||
|
||||
phase = 1 - phase;
|
||||
|
||||
return X;
|
||||
}
|
||||
|
||||
unsigned long writec2file(char *c2filename, int trmin, double freq
|
||||
, double *idat, double *qdat)
|
||||
{
|
||||
int i;
|
||||
float buffer[2*45000];
|
||||
memset(buffer,0,sizeof(float)*2*45000);
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen(c2filename,"wb");
|
||||
if( fp == NULL ) {
|
||||
fprintf(stderr, "Could not open c2 file '%s'\n", c2filename);
|
||||
return 0;
|
||||
}
|
||||
unsigned long nwrite = fwrite(c2filename,sizeof(char),14,fp);
|
||||
nwrite = fwrite(&trmin, sizeof(int), 1, fp);
|
||||
nwrite = fwrite(&freq, sizeof(double), 1, fp);
|
||||
|
||||
for(i=0; i<45000; i++) {
|
||||
buffer[2*i]=idat[i];
|
||||
buffer[2*i+1]=-qdat[i];
|
||||
}
|
||||
|
||||
nwrite = fwrite(buffer, sizeof(float), 2*45000, fp);
|
||||
if( nwrite == 2*45000 ) {
|
||||
return nwrite;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//********************************************************************
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
int i, c, printchannel=0, writec2=0;
|
||||
float snr=50.0;
|
||||
char *message, *c2filename, *hashtab;
|
||||
c2filename=malloc(sizeof(char)*15);
|
||||
hashtab=malloc(sizeof(char)*32768*13);
|
||||
memset(hashtab,0,sizeof(char)*32768*13);
|
||||
|
||||
// message length is 22 characters
|
||||
message=malloc(sizeof(char)*23);
|
||||
|
||||
strcpy(c2filename,"000000_0001.c2");
|
||||
|
||||
srand(getpid());
|
||||
|
||||
while ( (c = getopt(argc, argv, "cdo:s:")) !=-1 ) {
|
||||
switch (c) {
|
||||
case 'c':
|
||||
printchannel=1;
|
||||
break;
|
||||
case 'd':
|
||||
printdata=1;
|
||||
break;
|
||||
case 'o':
|
||||
c2filename = optarg;
|
||||
writec2=1;
|
||||
break;
|
||||
case 's':
|
||||
snr = (float)atoi(optarg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( optind+1 > argc ) {
|
||||
usage();
|
||||
return 0;
|
||||
} else {
|
||||
message=argv[optind];
|
||||
}
|
||||
|
||||
unsigned char channel_symbols[162];
|
||||
get_wspr_channel_symbols(message, hashtab, channel_symbols);
|
||||
|
||||
if( printchannel ) {
|
||||
printf("Channel symbols:\n");
|
||||
for (i=0; i<162; i++) {
|
||||
printf("%d ",channel_symbols[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
// add noise, then signal
|
||||
double isig[45000], qsig[45000];
|
||||
memset(isig,0,sizeof(double)*45000);
|
||||
memset(qsig,0,sizeof(double)*45000);
|
||||
|
||||
if( snr < 40 ) {
|
||||
// snr in 375Hz is 8.2 dB higher than in 2500 Hz.
|
||||
snr=snr+8.2;
|
||||
snr=pow(10,snr/20.0)*pow(2,0.5);
|
||||
|
||||
for (i = 0; i<45000; i++) {
|
||||
isig[i]=isig[i]+gaussrand();
|
||||
qsig[i]=qsig[i]+gaussrand();
|
||||
}
|
||||
} else {
|
||||
snr=1.0;
|
||||
}
|
||||
|
||||
float f0, t0;
|
||||
f0=0.0;
|
||||
t0=1.0;
|
||||
add_signal_vector(f0, t0, snr, channel_symbols, isig, qsig);
|
||||
if( writec2) {
|
||||
// write a .c2 file
|
||||
double carrierfreq=10.1387;
|
||||
int wsprtype=2;
|
||||
printf("Writing %s\n",c2filename);
|
||||
writec2file(c2filename, wsprtype, carrierfreq, isig, qsig);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
! LDPC (174,87) code
|
||||
parameter (KK=87) !Information bits (75 + CRC12)
|
||||
parameter (ND=58) !Data symbols
|
||||
parameter (NS=21) !Sync symbols (3 @ Costas 7x7)
|
||||
parameter (NN=NS+ND) !Total channel symbols (79)
|
||||
parameter (NSPS=1920) !Samples per symbol at 12000 S/s
|
||||
parameter (NZ=NSPS*NN) !Samples in full 15 s waveform (151,680)
|
||||
parameter (NMAX=15*12000) !Samples in iwave (180,000)
|
||||
parameter (NFFT1=2*NSPS, NH1=NFFT1/2) !Length of FFTs for symbol spectra
|
||||
parameter (NHSYM=2*NMAX/NH1-1) !Number of symbol spectra (1/2-sym steps)
|
||||
parameter (NDOWN=60) !Downsample factor
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 83 KiB |
File diff suppressed because it is too large
Load Diff
@@ -1,94 +0,0 @@
|
||||
Notes on WSJT-X Installation for Mac OS X
|
||||
-----------------------------------------
|
||||
|
||||
If you have already downloaded a previous version of WSJT-X then I suggest
|
||||
you change the name in the Applications folder from WSJT-X to WSJT-X_previous
|
||||
before proceeding.
|
||||
|
||||
If you have installed a previous version of WSJT-X before then there is no
|
||||
need to change anything on your system so proceed to NEXT.
|
||||
|
||||
BEGIN:
|
||||
|
||||
There are some system matters you must deal with first. Open a Terminal window
|
||||
by going to Applications->Utilities and clicking on Terminal.
|
||||
|
||||
Along with this ReadMe file there is a file: sysctl.conf. Drag this file to your Desktop.
|
||||
|
||||
WSJT-X makes use of a block of memory which is shared between different parts of
|
||||
the code. The normal allocation of shared memory on a Mac is insufficient and this
|
||||
has to be increased. You can check the current allocation on your Mac by typing:
|
||||
|
||||
sysctl -a | grep sysv.shm
|
||||
|
||||
If your shmmax is already at least 33554432 (32 MB) then you can close the Terminal
|
||||
window and skip the next steps and go to (NEXT).
|
||||
|
||||
Now move this file into place for the system to use by typing: (Note this assumes that
|
||||
you really did drag this file to your Desktop as required earlier.)
|
||||
|
||||
sudo cp $HOME/Desktop/sysctl.conf /etc/
|
||||
sudo chmod 664 /etc/sysctl.conf
|
||||
sudo chown root:wheel /etc/sysctl.conf
|
||||
|
||||
and then reboot your Mac. This is necessary to install the changes. After the
|
||||
reboot you should re-open the Terminal window as before and you can check that the
|
||||
change has been made by typing:
|
||||
|
||||
sysctl -a | grep sysv.shm
|
||||
|
||||
If shmmax is not shown as 33554432 then contact me since WSJT-X will fail to load with
|
||||
an error message: "Unable to create shared memory segment".
|
||||
|
||||
You are now finished with system changes. You should make certain that NO error messages
|
||||
have been produced during these steps. You can now close the Terminal window. It will
|
||||
not be necessary to repeat this procedure again, even when you download an updated
|
||||
version of WSJT-X.
|
||||
|
||||
NEXT:
|
||||
|
||||
Drag the WSJT-X app to your preferred location, such as Applications.
|
||||
|
||||
You need to configure your sound card. Visit Applications > Utilities > Audio MIDI
|
||||
Setup and select your sound card and then set Format to be "48000Hz 2ch-16bit" for
|
||||
input and output.
|
||||
|
||||
Now double-click on the WSJT-X app and two windows will appear. Select Preferences
|
||||
under the WSJT-X Menu and fill in various station details on the General panel.
|
||||
I recommend checking the 4 boxes under the Display heading and the first 4 boxes under
|
||||
the Behaviour heading.
|
||||
|
||||
Next visit the Audio panel and select the Audio Codec you use to communicate between
|
||||
WSJT-X and your rig. There are so many audio interfaces available that it is not
|
||||
possible to give detailed advice on selection. If you have difficulties contact me.
|
||||
Note the location of the Save Directory. Decoded wave forms are located here.
|
||||
|
||||
Look at the Reporting panel. If you check the "Prompt me" box, a logging panel will appear
|
||||
at the end of the QSO. Two log files are provided in Library/Application Support/WSJT-X.
|
||||
These are a simple wsjtx.log file and wsjtx_log.adi which is formatted for use with
|
||||
logging databases. The "File" menu bar items include a button "Open log directory"
|
||||
to open the log directory in Finder for you, ready for processing by any logging
|
||||
application you use.
|
||||
|
||||
Finally, visit the Radio panel. WSJT-X is most effective when operated with CAT
|
||||
control. You will need to install the relevant Mac driver for your rig. This must
|
||||
be located in the device driver directory /dev. You should install your driver
|
||||
and then re-launch WSJT-X. Return to the the Radio panel in Preferences and in
|
||||
the "Serial port" panel select your driver from the list that is presented. If
|
||||
for some reason your driver is not shown, then insert the full name
|
||||
of your driver in the Serial Port panel. Such as: /dev/tty.PL2303-00002226 or
|
||||
whatever driver you have. The /dev/ prefix is mandatory. Set the relevant
|
||||
communication parameters as required by your transceiver and click "Test CAT" to
|
||||
check.
|
||||
|
||||
WSJT-X needs the Mac clock to be accurate. Visit System Preferences > Date & Time
|
||||
and make sure that date and time are set automatically. The drop-down menu will
|
||||
normally offer you several time servers to choose from.
|
||||
|
||||
On the Help menu, have a look at the new Online User's Guide for operational hints
|
||||
and tips.
|
||||
|
||||
Please email me if you have problems.
|
||||
|
||||
--- John G4KLA (g4kla@rmnjmn.co.uk)
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
#ifndef MODULATOR_HPP__
|
||||
#define MODULATOR_HPP__
|
||||
|
||||
#include <QAudio>
|
||||
#include <QPointer>
|
||||
|
||||
#include "AudioDevice.hpp"
|
||||
|
||||
class SoundOutput;
|
||||
|
||||
//
|
||||
// Input device that generates PCM audio frames that encode a message
|
||||
// and an optional CW ID.
|
||||
//
|
||||
// Output can be muted while underway, preserving waveform timing when
|
||||
// transmission is resumed.
|
||||
//
|
||||
class Modulator
|
||||
: public AudioDevice
|
||||
{
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
enum ModulatorState {Synchronizing, Active, Idle};
|
||||
|
||||
Modulator (unsigned frameRate, unsigned periodLengthInSeconds, QObject * parent = nullptr);
|
||||
|
||||
void close () override;
|
||||
|
||||
bool isTuning () const {return m_tuning;}
|
||||
double frequency () const {return m_frequency;}
|
||||
bool isActive () const {return m_state != Idle;}
|
||||
void setSpread(double s) {m_fSpread=s;}
|
||||
void setTRPeriod(unsigned p) {m_period=p;}
|
||||
void set_nsym(int n) {m_symbolsLength=n;}
|
||||
|
||||
Q_SLOT void start (unsigned symbolsLength, double framesPerSymbol, double frequency,
|
||||
double toneSpacing, SoundOutput *, Channel = Mono,
|
||||
bool synchronize = true, bool fastMode = false,
|
||||
double dBSNR = 99., int TRperiod=60);
|
||||
Q_SLOT void stop (bool quick = false);
|
||||
Q_SLOT void tune (bool newState = true);
|
||||
Q_SLOT void setFrequency (double newFrequency) {m_frequency = newFrequency;}
|
||||
Q_SIGNAL void stateChanged (ModulatorState) const;
|
||||
|
||||
protected:
|
||||
qint64 readData (char * data, qint64 maxSize) override;
|
||||
qint64 writeData (char const * /* data */, qint64 /* maxSize */) override
|
||||
{
|
||||
return -1; // we don't consume data
|
||||
}
|
||||
|
||||
private:
|
||||
qint16 postProcessSample (qint16 sample) const;
|
||||
|
||||
QPointer<SoundOutput> m_stream;
|
||||
bool m_quickClose;
|
||||
|
||||
unsigned m_symbolsLength;
|
||||
|
||||
static double constexpr m_twoPi = 2.0 * 3.141592653589793238462;
|
||||
unsigned m_nspd = 2048 + 512; // CW ID WPM factor = 22.5 WPM
|
||||
|
||||
double m_phi;
|
||||
double m_dphi;
|
||||
double m_amp;
|
||||
double m_nsps;
|
||||
double volatile m_frequency;
|
||||
double m_frequency0;
|
||||
double m_snr;
|
||||
double m_fac;
|
||||
double m_toneSpacing;
|
||||
double m_fSpread;
|
||||
|
||||
qint64 m_silentFrames;
|
||||
qint32 m_TRperiod;
|
||||
qint16 m_ramp;
|
||||
|
||||
unsigned m_frameRate;
|
||||
unsigned m_period;
|
||||
ModulatorState volatile m_state;
|
||||
|
||||
bool volatile m_tuning;
|
||||
bool m_addNoise;
|
||||
bool m_bFastMode;
|
||||
|
||||
bool m_cwLevel;
|
||||
unsigned m_ic;
|
||||
unsigned m_isym0;
|
||||
int m_j0;
|
||||
double m_toneFrequency0;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user