Merged master 8748

This commit is contained in:
Jordan Sherer
2018-08-05 11:33:30 -04:00
parent 8f8772f1bd
commit 62899069bf
1222 changed files with 70382 additions and 406763 deletions
@@ -1,187 +0,0 @@
program chkfft
! Tests and times one-dimensional FFTs computed by FFTW3
use FFTW3
parameter (NMAX=8*1024*1024) !Maximum FFT length
complex a(NMAX),b(NMAX),c(NMAX)
real ar(NMAX),br(NMAX),cr(NMAX)
real mflops
integer*8 plan1,plan2 !Pointers to stored plans
character infile*12,arg*8
logical list
common/patience/npatience
equivalence (a,ar),(b,br),(c,cr)
! include 'fftw3.f90' !FFTW definitions
nargs=iargc()
if(nargs.ne.6) then
print*,'Usage: chkfft <nfft | infile> nr nw nc np inplace'
print*,' nfft: length of FFT'
print*,' nfft=0: do lengths 2^n, n=2^4 to 2^23'
print*,' infile: name of file with nfft values, one per line'
print*,' nr: 0/1 to not read (or read) wisdom'
print*,' nw: 0/1 to not write (or write) wisdom'
print*,' nc: 0/1 for real or complex data'
print*,' np: 0-4 patience for finding best algorithm'
print*,' inplace: 1 for inplace, 0 otherwise'
go to 999
endif
list=.false.
nfft=-1
call getarg(1,infile)
open(10,file=infile,status='old',err=1)
list=.true. !A valid file name was provided
go to 2
1 read(infile,*) nfft !Take first argument to be nfft
2 call getarg(2,arg)
read(arg,*) nr
call getarg(3,arg)
read(arg,*) nw
call getarg(4,arg)
read(arg,*) ncomplex
call getarg(5,arg)
read(arg,*) npatience
call getarg(6,arg)
read(arg,*) inplace
if(list) write(*,1000) infile,nr,nw,ncomplex,npatience
1000 format(/'infile: ',a12,' nr:',i2,' nw',i2,' nc:',i2,' np:',i2/)
if(.not.list) write(*,1002) nfft,nr,nw,ncomplex,npatience
1002 format(/'nfft: ',i10,' nr:',i2,' nw',i2,' nc:',i2,' np:',i2/)
nflags=FFTW_ESTIMATE
if(npatience.eq.1) nflags=FFTW_ESTIMATE_PATIENT
if(npatience.eq.2) nflags=FFTW_MEASURE
if(npatience.eq.3) nflags=FFTW_PATIENT
if(npatience.eq.4) nflags=FFTW_EXHAUSTIVE
open(12,file='chkfft.out',status='unknown')
open(13,file='fftwf_wisdom.dat',status='unknown')
if(nr.ne.0) then
call import_wisdom_from_file(isuccess,13)
if(isuccess.eq.0) then
write(*,1010)
1010 format('Failed to import FFTW wisdom.')
go to 999
endif
endif
idum=-1 !Set random seed
ndim=1 !One-dimensional transforms
do i=1,NMAX !Set random data
x=gran()
y=gran()
b(i)=cmplx(x,y) !Generate random data
enddo
iters=1000000
if(list .or. (nfft.gt.0)) then
n1=1
n2=1
if(nfft.eq.-1) n2=999999
write(*,1020)
1020 format(' NFFT Time rms MHz MFlops iters', &
' tplan'/61('-'))
else
n1=4
n2=23
write(*,1030)
1030 format(' n N=2^n Time rms MHz MFlops iters', &
' tplan'/63('-'))
endif
do ii=n1,n2 !Test one or more FFT lengths
if(list) then
read(10,*,end=900) nfft !Read nfft from file
else if(n2.gt.n1) then
nfft=2**ii !Do powers of 2
endif
iformf=1
iformb=1
if(ncomplex.eq.0) then
iformf=0 !Real-to-complex transform
iformb=-1 !Complex-to-real (inverse) transform
endif
if(nfft.gt.NMAX) go to 900
a(1:nfft)=b(1:nfft) !Copy test data into a()
t0=second()
if(inplace.ne.0) then
if(ncomplex.ne.0) then
call sfftw_plan_dft_1d(plan1,nfft,a,a,FFTW_FORWARD,nflags)
call sfftw_plan_dft_1d(plan2,nfft,a,a,FFTW_BACKWARD,nflags)
else
call sfftw_plan_dft_r2c_1d(plan1,nfft,a,a,nflags)
call sfftw_plan_dft_c2r_1d(plan2,nfft,a,a,nflags)
endif
else
if(ncomplex.ne.0) then
call sfftw_plan_dft_1d(plan1,nfft,a,c,FFTW_FORWARD,nflags)
call sfftw_plan_dft_1d(plan2,nfft,c,a,FFTW_BACKWARD,nflags)
else
call sfftw_plan_dft_r2c_1d(plan1,nfft,a,c,nflags)
call sfftw_plan_dft_c2r_1d(plan2,nfft,c,a,nflags)
endif
endif
t2=second()
tplan=t2-t0 !Total planning time for this length
total=0.
do iter=1,iters !Now do many iterations
a(1:nfft)=b(1:nfft) !Copy test data into a()
t0=second()
call sfftw_execute(plan1)
call sfftw_execute(plan2)
t1=second()
total=total+t1-t0
if(total.ge.1.0) go to 40 !Cut iterations short if t>1 s
enddo
iter=iters
40 time=0.5*total/iter !Time for one FFT of current length
tplan=0.5*tplan-time !Planning time for one FFT
if(tplan.lt.0) tplan=0.
a(1:nfft)=a(1:nfft)/nfft
! Compute RMS difference between original array and back-transformed array.
sq=0.
if(ncomplex.eq.1) then
do i=1,nfft
sq=sq + real(a(i)-b(i))**2 + imag(a(i)-b(i))**2
enddo
else
do i=1,nfft
sq=sq + (ar(i)-br(i))**2
enddo
endif
rms=sqrt(sq/nfft)
freq=1.e-6*nfft/time
mflops=5.0/(1.e6*time/(nfft*log(float(nfft))/log(2.0)))
if(n2.eq.1 .or. n2.eq.999999) then
write(*,1050) nfft,time,rms,freq,mflops,iter,tplan
write(12,1050) nfft,time,rms,freq,mflops,iter,tplan
1050 format(i8,f11.7,f12.8,f7.2,f8.1,i8,f6.1)
else
write(*,1060) ii,nfft,time,rms,freq,mflops,iter,tplan
write(12,1060) ii,nfft,time,rms,freq,mflops,iter,tplan
1060 format(i2,i8,f11.7,f12.8,f7.2,f8.1,i8,f6.1)
endif
enddo
900 continue
if(nw.eq.1) then
rewind 13
call export_wisdom_to_file(13)
! write(*,1070)
!1070 format(/'Exported FFTW wisdom')
endif
call sfftw_destroy_plan(plan1)
call sfftw_destroy_plan(plan2)
999 end program chkfft
@@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
@@ -1,73 +0,0 @@
subroutine sync8(iwave,xdt,f1,s)
include 'ft8_params.f90'
parameter (IZ=10,JZ=20)
complex cx(0:NH1)
real s(NH1,NHSYM)
real savg(NH1)
real x(NFFT1)
real sync2d(-IZ:IZ,-JZ:JZ)
integer*2 iwave(NMAX)
integer icos7(0:6)
data icos7/2,5,6,0,4,1,3/ !Costas 7x7 tone pattern
equivalence (x,cx)
! Compute symbol spectra at half-symbol steps.
savg=0.
istep=NSPS/2
tstep=istep/12000.0
df=12000.0/NFFT1
fac=1.0/300.0
do j=1,NHSYM
ia=(j-1)*istep + 1
ib=ia+NSPS-1
x(1:NSPS)=fac*iwave(ia:ib)
x(NSPS+1:)=0.
call four2a(x,NFFT1,1,-1,0) !r2c FFT
do i=1,NH1
s(i,j)=real(cx(i))**2 + aimag(cx(i))**2
enddo
savg=savg + s(1:NH1,j)
enddo
ia=nint(30.0/df)
ib=nint(3000.0/df)
savg=savg/NHSYM
pmax=0.
i0=0
do i=ia,ib
p=sum(savg(i-8:i+8))/17.0
if(p.gt.pmax) then
pmax=p
i0=i-7
endif
enddo
tmax=0.
ipk=0
jpk=0
j0=1
do i=-IZ,IZ
do j=-JZ,JZ
t=0.
do n=0,6
k=j0+j+2*n
if(k.ge.1) t=t + s(i0+i+2*icos7(n),k)
t=t + s(i0+i+2*icos7(n),k+72)
if(k+144.le.NHSYM) t=t + s(i0+i+2*icos7(n),k+144)
enddo
sync2d(i,j)=t
if(t.gt.tmax) then
tmax=t
jpk=j
ipk=i
endif
enddo
enddo
f0=i0*df
f1=(i0+ipk)*df
xdt=jpk*tstep
return
end subroutine sync8
@@ -1,46 +0,0 @@
#!/bin/sh
# Example of a (10000,5000) LDPC code with varying numbers of check per bit,
# tested on Additive White Gaussian Noise channels with noise standard
# deviations varying from 0.80 to 0.95. The code has 20% columns with two
# check bits, 70% columns with three check bits, and 10% columns with seven
# check bits.
#
# Testing is done by transmitting random messages, with pipes used so that
# intermediate files are avoided. Decoding is done using a maximum of 250
# iterations of probability propagation.
set -e # Stop if an error occurs
set -v # Echo commands as they are read
make-ldpc ex-ldpcvar-5000a.pchk 5000 10000 2 evenboth 2x2/7x3/1x7 no4cycle
make-gen ex-ldpcvar-5000a.pchk ex-ldpcvar-5000a.gen dense
rand-src ex-ldpcvar-5000a.src 1 5000x100
# NOISE STANDARD DEVIATION 0.80, Eb/N0 = 1.94 dB
encode ex-ldpcvar-5000a.pchk ex-ldpcvar-5000a.gen ex-ldpcvar-5000a.src - \
| transmit - - 1 awgn 0.80 \
| decode ex-ldpcvar-5000a.pchk - - awgn 0.80 prprp 250 \
| verify ex-ldpcvar-5000a.pchk - ex-ldpcvar-5000a.gen ex-ldpcvar-5000a.src
# NOISE STANDARD DEVIATION 0.85, Eb/N0 = 1.41 dB
encode ex-ldpcvar-5000a.pchk ex-ldpcvar-5000a.gen ex-ldpcvar-5000a.src - \
| transmit - - 1 awgn 0.85 \
| decode ex-ldpcvar-5000a.pchk - - awgn 0.85 prprp 250 \
| verify ex-ldpcvar-5000a.pchk - ex-ldpcvar-5000a.gen ex-ldpcvar-5000a.src
# NOISE STANDARD DEVIATION 0.90, Eb/N0 = 0.92 dB
encode ex-ldpcvar-5000a.pchk ex-ldpcvar-5000a.gen ex-ldpcvar-5000a.src - \
| transmit - - 1 awgn 0.90 \
| decode ex-ldpcvar-5000a.pchk - - awgn 0.90 prprp 250 \
| verify ex-ldpcvar-5000a.pchk - ex-ldpcvar-5000a.gen ex-ldpcvar-5000a.src
# NOISE STANDARD DEVIATION 0.95, Eb/N0 = 0.45 dB
encode ex-ldpcvar-5000a.pchk ex-ldpcvar-5000a.gen ex-ldpcvar-5000a.src - \
| transmit - - 1 awgn 0.95 \
| decode ex-ldpcvar-5000a.pchk - - awgn 0.95 prprp 250 \
| verify ex-ldpcvar-5000a.pchk - ex-ldpcvar-5000a.gen ex-ldpcvar-5000a.src
@@ -1,123 +0,0 @@
#include "fastgraph.h"
#include "commons.h"
#include <QSettings>
#include <QApplication>
#include "fastplot.h"
#include "SettingsGroup.hpp"
#include "ui_fastgraph.h"
#include "moc_fastgraph.cpp"
#define NSMAX2 1366
FastGraph::FastGraph(QSettings * settings, QWidget *parent) :
QDialog {parent, Qt::Window | Qt::WindowTitleHint |
Qt::WindowCloseButtonHint |
Qt::WindowMinimizeButtonHint},
m_settings {settings},
m_ave {40},
ui {new Ui::FastGraph}
{
ui->setupUi(this);
setWindowTitle (QApplication::applicationName () + " - " + tr ("Fast Graph"));
installEventFilter(parent); //Installing the filter
ui->fastPlot->setCursor(Qt::CrossCursor);
//Restore user's settings
SettingsGroup g {m_settings, "FastGraph"};
restoreGeometry (m_settings->value ("geometry", saveGeometry ()).toByteArray ());
ui->fastPlot->setPlotZero(m_settings->value("PlotZero", 0).toInt());
ui->fastPlot->setPlotGain(m_settings->value("PlotGain", 0).toInt());
ui->zeroSlider->setValue(ui->fastPlot->m_plotZero);
ui->gainSlider->setValue(ui->fastPlot->m_plotGain);
ui->fastPlot->setGreenZero(m_settings->value("GreenZero", 0).toInt());
ui->greenZeroSlider->setValue(ui->fastPlot->m_greenZero);
ui->controls_widget->setVisible (!m_settings->value("HideControls", false).toBool ());
connect (ui->fastPlot, &FPlotter::fastPick, this, &FastGraph::fastPick);
}
void FastGraph::closeEvent (QCloseEvent * e)
{
saveSettings ();
QDialog::closeEvent (e);
}
FastGraph::~FastGraph ()
{
}
void FastGraph::saveSettings()
{
//Save user's settings
SettingsGroup g {m_settings, "FastGraph"};
m_settings->setValue ("geometry", saveGeometry ());
m_settings->setValue("PlotZero",ui->fastPlot->m_plotZero);
m_settings->setValue("PlotGain",ui->fastPlot->m_plotGain);
m_settings->setValue("GreenZero",ui->fastPlot->m_greenZero);
m_settings->setValue("GreenGain",ui->fastPlot->m_greenGain);
m_settings->setValue ("HideControls", ui->controls_widget->isHidden ());
}
void FastGraph::plotSpec(bool diskData, int UTCdisk)
{
ui->fastPlot->m_diskData=diskData;
ui->fastPlot->m_UTCdisk=UTCdisk;
ui->fastPlot->draw();
}
void FastGraph::on_gainSlider_valueChanged(int value)
{
ui->fastPlot->setPlotGain(value);
ui->fastPlot->draw();
}
void FastGraph::on_zeroSlider_valueChanged(int value)
{
ui->fastPlot->setPlotZero(value);
ui->fastPlot->draw();
}
void FastGraph::on_greenZeroSlider_valueChanged(int value)
{
ui->fastPlot->setGreenZero(value);
ui->fastPlot->draw();
}
void FastGraph::setTRperiod(int n)
{
m_TRperiod=n;
ui->fastPlot->setTRperiod(m_TRperiod);
}
void FastGraph::on_pbAutoLevel_clicked()
{
float sum=0.0;
for(int i=0; i<=fast_jh; i++) {
sum += fast_green[i];
}
m_ave=sum/fast_jh;
ui->gainSlider->setValue(127-int(2.2*m_ave));
ui->zeroSlider->setValue(int(m_ave)+20);
ui->greenZeroSlider->setValue(160-int(3.3*m_ave));
}
void FastGraph::setMode(QString mode) //setMode
{
ui->fastPlot->setMode(mode);
}
void FastGraph::keyPressEvent(QKeyEvent *e)
{
switch(e->key())
{
case Qt::Key_M:
if(e->modifiers() & Qt::ControlModifier) {
ui->controls_widget->setVisible (!ui->controls_widget->isVisible ());
}
break;
default:
QDialog::keyPressEvent (e);
}
}
@@ -1,328 +0,0 @@
#include "Modulator.hpp"
#include <limits>
#include <qmath.h>
#include <QDateTime>
#include <QDebug>
#include "mainwindow.h"
#include "soundout.h"
#include "moc_Modulator.cpp"
extern float gran(); // Noise generator (for tests only)
#define RAMP_INCREMENT 64 // MUST be an integral factor of 2^16
#if defined (WSJT_SOFT_KEYING)
# define SOFT_KEYING WSJT_SOFT_KEYING
#else
# define SOFT_KEYING 1
#endif
double constexpr Modulator::m_twoPi;
// float wpm=20.0;
// unsigned m_nspd=1.2*48000.0/wpm;
// m_nspd=3072; //18.75 WPM
Modulator::Modulator (unsigned frameRate, unsigned periodLengthInSeconds,
QObject * parent)
: AudioDevice {parent}
, m_quickClose {false}
, m_phi {0.0}
, m_toneSpacing {0.0}
, m_fSpread {0.0}
, m_frameRate {frameRate}
, m_period {periodLengthInSeconds}
, m_state {Idle}
, m_tuning {false}
, m_cwLevel {false}
, m_j0 {-1}
, m_toneFrequency0 {1500.0}
{
}
void Modulator::start (unsigned symbolsLength, double framesPerSymbol,
double frequency, double toneSpacing,
SoundOutput * stream, Channel channel,
bool synchronize, bool fastMode, double dBSNR, int TRperiod)
{
Q_ASSERT (stream);
// Time according to this computer which becomes our base time
qint64 ms0 = QDateTime::currentMSecsSinceEpoch() % 86400000;
if (m_state != Idle)
{
stop ();
}
m_quickClose = false;
m_symbolsLength = symbolsLength;
m_isym0 = std::numeric_limits<unsigned>::max (); // big number
m_frequency0 = 0.;
m_phi = 0.;
m_addNoise = dBSNR < 0.;
m_nsps = framesPerSymbol;
m_frequency = frequency;
m_amp = std::numeric_limits<qint16>::max ();
m_toneSpacing = toneSpacing;
m_bFastMode=fastMode;
m_TRperiod=TRperiod;
// noise generator parameters
if (m_addNoise) {
m_snr = qPow (10.0, 0.05 * (dBSNR - 6.0));
m_fac = 3000.0;
if (m_snr > 1.0) m_fac = 3000.0 / m_snr;
}
unsigned mstr = ms0 % (1000 * m_period); // ms in period
m_ic = (mstr / 1000) * m_frameRate; // we start exactly N seconds
// into period where N is the next whole second
if(m_bFastMode) m_ic=0;
m_silentFrames = 0;
// calculate number of silent frames to send
if (synchronize && !m_tuning && !m_bFastMode) {
m_silentFrames = m_ic + m_frameRate - (mstr * m_frameRate / 1000);
}
if(m_ic==0 and (m_silentFrames/48000.0 > 0.6) and m_nsps==1920 and m_period==15) {
// FT8 mode: Start audio at t=0.5 s rather than t=1.0 s.
m_silentFrames=m_silentFrames-24000;
}
initialize (QIODevice::ReadOnly, channel);
Q_EMIT stateChanged ((m_state = (synchronize && m_silentFrames) ?
Synchronizing : Active));
m_stream = stream;
if (m_stream) m_stream->restart (this);
}
void Modulator::tune (bool newState)
{
m_tuning = newState;
if (!m_tuning) stop (true);
}
void Modulator::stop (bool quick)
{
m_quickClose = quick;
close ();
}
void Modulator::close ()
{
if (m_stream)
{
if (m_quickClose)
{
m_stream->reset ();
}
else
{
m_stream->stop ();
}
}
if (m_state != Idle)
{
Q_EMIT stateChanged ((m_state = Idle));
}
AudioDevice::close ();
}
qint64 Modulator::readData (char * data, qint64 maxSize)
{
double toneFrequency=1500.0;
if(m_nsps==6) {
toneFrequency=1000.0;
m_frequency=1000.0;
m_frequency0=1000.0;
}
if(maxSize==0) return 0;
Q_ASSERT (!(maxSize % qint64 (bytesPerFrame ()))); // no torn frames
Q_ASSERT (isOpen ());
qint64 numFrames (maxSize / bytesPerFrame ());
qint16 * samples (reinterpret_cast<qint16 *> (data));
qint16 * end (samples + numFrames * (bytesPerFrame () / sizeof (qint16)));
qint64 framesGenerated (0);
switch (m_state)
{
case Synchronizing:
{
if (m_silentFrames) { // send silence up to first second
framesGenerated = qMin (m_silentFrames, numFrames);
for ( ; samples != end; samples = load (0, samples)) { // silence
}
m_silentFrames -= framesGenerated;
return framesGenerated * bytesPerFrame ();
}
Q_EMIT stateChanged ((m_state = Active));
m_cwLevel = false;
m_ramp = 0; // prepare for CW wave shaping
}
// fall through
case Active:
{
unsigned int isym=0;
if(!m_tuning) isym=m_ic/(4.0*m_nsps); // Actual fsample=48000
bool slowCwId=((isym >= m_symbolsLength) && (icw[0] > 0)) && (!m_bFastMode);
if(m_TRperiod==3) slowCwId=false;
bool fastCwId=false;
static bool bCwId=false;
qint64 ms = QDateTime::currentMSecsSinceEpoch();
float tsec=0.001*(ms % (1000*m_TRperiod));
if(m_bFastMode and (icw[0]>0) and (tsec>(m_TRperiod-5.0))) fastCwId=true;
if(!m_bFastMode) m_nspd=2560; // 22.5 WPM
if(slowCwId or fastCwId) { // Transmit CW ID?
m_dphi = m_twoPi*m_frequency/m_frameRate;
if(m_bFastMode and !bCwId) {
m_frequency=1500; // Set params for CW ID
m_dphi = m_twoPi*m_frequency/m_frameRate;
m_symbolsLength=126;
m_nsps=4096.0*12000.0/11025.0;
m_ic=2246949;
m_nspd=2560; // 22.5 WPM
if(icw[0]*m_nspd/48000.0 > 4.0) m_nspd=4.0*48000.0/icw[0]; //Faster CW for long calls
}
bCwId=true;
unsigned ic0 = m_symbolsLength * 4 * m_nsps;
unsigned j(0);
while (samples != end) {
j = (m_ic - ic0)/m_nspd + 1; // symbol of this sample
bool level {bool (icw[j])};
m_phi += m_dphi;
if (m_phi > m_twoPi) m_phi -= m_twoPi;
qint16 sample=0;
float amp=32767.0;
float x=0;
if(m_ramp!=0) {
x=qSin(float(m_phi));
if(SOFT_KEYING) {
amp=qAbs(qint32(m_ramp));
if(amp>32767.0) amp=32767.0;
}
sample=round(amp*x);
}
if(m_bFastMode) {
sample=0;
if(level) sample=32767.0*x;
}
if (int (j) <= icw[0] && j < NUM_CW_SYMBOLS) { // stop condition
samples = load (postProcessSample (sample), samples);
++framesGenerated;
++m_ic;
} else {
Q_EMIT stateChanged ((m_state = Idle));
return framesGenerated * bytesPerFrame ();
}
// adjust ramp
if ((m_ramp != 0 && m_ramp != std::numeric_limits<qint16>::min ()) || level != m_cwLevel) {
// either ramp has terminated at max/min or direction has changed
m_ramp += RAMP_INCREMENT; // ramp
}
m_cwLevel = level;
}
return framesGenerated * bytesPerFrame ();
} else {
bCwId=false;
} //End of code for CW ID
double const baud (12000.0 / m_nsps);
// fade out parameters (no fade out for tuning)
unsigned int i0,i1;
if(m_tuning) {
i1 = i0 = (m_bFastMode ? 999999 : 9999) * m_nsps;
} else {
i0=(m_symbolsLength - 0.017) * 4.0 * m_nsps;
i1= m_symbolsLength * 4.0 * m_nsps;
}
if(m_bFastMode and !m_tuning) {
i1=m_TRperiod*48000 - 24000;
i0=i1-816;
}
for (unsigned i = 0; i < numFrames && m_ic <= i1; ++i) {
isym=0;
if(!m_tuning and m_TRperiod!=3) isym=m_ic / (4.0 * m_nsps); //Actual fsample=48000
if(m_bFastMode) isym=isym%m_symbolsLength;
if (isym != m_isym0 || m_frequency != m_frequency0) {
if(itone[0]>=100) {
m_toneFrequency0=itone[0];
} else {
if(m_toneSpacing==0.0) {
m_toneFrequency0=m_frequency + itone[isym]*baud;
} else {
m_toneFrequency0=m_frequency + itone[isym]*m_toneSpacing;
}
}
// qDebug() << "B" << m_bFastMode << m_ic << numFrames << isym << itone[isym]
// << m_toneFrequency0 << m_nsps;
m_dphi = m_twoPi * m_toneFrequency0 / m_frameRate;
m_isym0 = isym;
m_frequency0 = m_frequency; //???
}
int j=m_ic/480;
if(m_fSpread>0.0 and j!=m_j0) {
float x1=(float)qrand()/RAND_MAX;
float x2=(float)qrand()/RAND_MAX;
toneFrequency = m_toneFrequency0 + 0.5*m_fSpread*(x1+x2-1.0);
m_dphi = m_twoPi * toneFrequency / m_frameRate;
m_j0=j;
}
m_phi += m_dphi;
if (m_phi > m_twoPi) m_phi -= m_twoPi;
if (m_ic > i0) m_amp = 0.98 * m_amp;
if (m_ic > i1) m_amp = 0.0;
samples = load (postProcessSample (m_amp * qSin (m_phi)), samples);
++framesGenerated;
++m_ic;
}
if (m_amp == 0.0) { // TODO G4WJS: compare double with zero might not be wise
if (icw[0] == 0) {
// no CW ID to send
Q_EMIT stateChanged ((m_state = Idle));
return framesGenerated * bytesPerFrame ();
}
m_phi = 0.0;
}
m_frequency0 = m_frequency;
// done for this chunk - continue on next call
return framesGenerated * bytesPerFrame ();
}
// fall through
case Idle:
break;
}
Q_ASSERT (Idle == m_state);
return 0;
}
qint16 Modulator::postProcessSample (qint16 sample) const
{
if (m_addNoise) { // Test frame, we'll add noise
qint32 s = m_fac * (gran () + sample * m_snr / 32768.0);
if (s > std::numeric_limits<qint16>::max ()) {
s = std::numeric_limits<qint16>::max ();
}
if (s < std::numeric_limits<qint16>::min ()) {
s = std::numeric_limits<qint16>::min ();
}
sample = s;
}
return sample;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB