Phase accumulator

* Corrected phase accumulator limits in cw, feld,
    dominoex and thor modems.
pull/1/head
David Freese 2014-08-29 03:53:49 -05:00
rodzic 947ebc9ff5
commit a1c3f7a937
14 zmienionych plików z 40 dodań i 89 usunięć

Wyświetl plik

@ -114,9 +114,8 @@ complex BLANK::mixer(complex in, double f)
z = in * complex( cos(phaseacc), sin(phaseacc) ); z = in * complex( cos(phaseacc), sin(phaseacc) );
phaseacc -= TWOPI * f / corrRxSampleRate(); phaseacc -= TWOPI * f / corrRxSampleRate();
if (phaseacc > TWOPI) phaseacc -= TWOPI; if (phaseacc < 0) phaseacc += TWOPI;
if (phaseacc < -TWOPI) phaseacc += TWOPI;
return z; return z;
} }

Wyświetl plik

@ -46,8 +46,8 @@ double contestia::nco(double freq)
{ {
preamblephase += 2.0 * M_PI * freq / samplerate; preamblephase += 2.0 * M_PI * freq / samplerate;
if (preamblephase > M_PI) if (preamblephase > TWOPI)
preamblephase -= 2.0 * M_PI; preamblephase -= TWOPI;
return cos(preamblephase); return cos(preamblephase);
} }

Wyświetl plik

@ -536,10 +536,7 @@ cmplx cw::mixer(cmplx in)
z = z * in; z = z * in;
phaseacc += TWOPI * frequency / samplerate; phaseacc += TWOPI * frequency / samplerate;
if (phaseacc > M_PI) if (phaseacc > TWOPI) phaseacc -= TWOPI;
phaseacc -= TWOPI;
else if (phaseacc < M_PI)
phaseacc += TWOPI;
return z; return z;
} }
@ -618,10 +615,7 @@ void cw::rx_FFTprocess(const double *buf, int len)
z = cmplx ( *buf * cos(FFTphase), *buf * sin(FFTphase) ); z = cmplx ( *buf * cos(FFTphase), *buf * sin(FFTphase) );
FFTphase += TWOPI * frequency / samplerate; FFTphase += TWOPI * frequency / samplerate;
if (FFTphase > M_PI) if (FFTphase > TWOPI) FFTphase -= TWOPI;
FFTphase -= TWOPI;
else if (FFTphase < M_PI)
FFTphase += TWOPI;
buf++; buf++;
@ -655,10 +649,7 @@ void cw::rx_FIRprocess(const double *buf, int len)
buf++; buf++;
FIRphase += TWOPI * frequency / samplerate; FIRphase += TWOPI * frequency / samplerate;
if (FIRphase > M_PI) if (FIRphase > TWOPI) FIRphase -= TWOPI;
FIRphase -= TWOPI;
else if (FIRphase < M_PI)
FIRphase += TWOPI;
if (cw_FIR_filter->run ( z, z )) { if (cw_FIR_filter->run ( z, z )) {
@ -910,8 +901,7 @@ inline double cw::nco(double freq)
{ {
phaseacc += 2.0 * M_PI * freq / samplerate; phaseacc += 2.0 * M_PI * freq / samplerate;
if (phaseacc > M_PI) if (phaseacc > TWOPI) phaseacc -= TWOPI;
phaseacc -= 2.0 * M_PI;
return sin(phaseacc); return sin(phaseacc);
} }
@ -920,8 +910,7 @@ inline double cw::qsknco()
{ {
qskphase += 2.0 * M_PI * 1000 / samplerate; qskphase += 2.0 * M_PI * 1000 / samplerate;
if (qskphase > M_PI) if (qskphase > TWOPI) qskphase -= TWOPI;
qskphase -= 2.0 * M_PI;
return sin(qskphase); return sin(qskphase);
} }

Wyświetl plik

@ -843,8 +843,7 @@ double rtty::nco(double freq)
{ {
phaseacc += TWOPI * freq / samplerate; phaseacc += TWOPI * freq / samplerate;
if (phaseacc > M_PI) if (phaseacc > TWOPI) phaseacc -= TWOPI;
phaseacc -= TWOPI;
return cos(phaseacc); return cos(phaseacc);
} }
@ -853,9 +852,7 @@ double rtty::FSKnco()
{ {
FSKphaseacc += TWOPI * 1000 / samplerate; FSKphaseacc += TWOPI * 1000 / samplerate;
if (FSKphaseacc > M_PI) if (FSKphaseacc > TWOPI) FSKphaseacc -= TWOPI;
FSKphaseacc -= TWOPI;
return sin(FSKphaseacc); return sin(FSKphaseacc);
@ -1246,7 +1243,8 @@ Oscillator::Oscillator( double samplerate )
double Oscillator::Update( double frequency ) double Oscillator::Update( double frequency )
{ {
m_phase += frequency/m_samplerate * TWOPI; m_phase += frequency/m_samplerate * TWOPI;
if ( m_phase > M_PI ) m_phase -= TWOPI; if ( m_phase > TWOPI ) m_phase -= TWOPI;
return ( sin( m_phase ) ); return ( sin( m_phase ) );
} }

Wyświetl plik

@ -335,10 +335,8 @@ cmplx dominoex::mixer(int n, cmplx in)
z = cmplx( cos(phase[n]), sin(phase[n])); z = cmplx( cos(phase[n]), sin(phase[n]));
z = z * in; z = z * in;
phase[n] -= TWOPI * f / samplerate; phase[n] -= TWOPI * f / samplerate;
if (phase[n] > M_PI) if (phase[n] < 0) phase[n] += TWOPI;
phase[n] -= TWOPI;
else if (phase[n] < M_PI)
phase[n] += TWOPI;
return z; return z;
} }
@ -632,10 +630,7 @@ void dominoex::sendtone(int tone, int duration)
for (int i = 0; i < symlen; i++) { for (int i = 0; i < symlen; i++) {
outbuf[i] = cos(txphase); outbuf[i] = cos(txphase);
txphase -= phaseincr; txphase -= phaseincr;
if (txphase > M_PI) if (txphase < 0) txphase += TWOPI;
txphase -= TWOPI;
else if (txphase < M_PI)
txphase += TWOPI;
} }
ModulateXmtr(outbuf, symlen); ModulateXmtr(outbuf, symlen);
} }

Wyświetl plik

@ -222,10 +222,7 @@ cmplx feld::mixer(cmplx in)
rxphacc -= 2.0 * M_PI * frequency / samplerate; rxphacc -= 2.0 * M_PI * frequency / samplerate;
if (rxphacc > M_PI) if (rxphacc < 0) rxphacc += TWOPI;
rxphacc -= 2.0 * M_PI;
else if (rxphacc < M_PI)
rxphacc += 2.0 * M_PI;
return z; return z;
} }
@ -451,8 +448,7 @@ double feld::nco(double freq)
txphacc += 2.0 * M_PI * freq / samplerate; txphacc += 2.0 * M_PI * freq / samplerate;
if (txphacc > M_PI) if (txphacc > TWOPI) txphacc -= TWOPI;
txphacc -= 2.0 * M_PI;
return x; return x;
} }

Wyświetl plik

@ -677,8 +677,7 @@ cmplx mfsk::mixer(cmplx in, double f)
z = in * cmplx( cos(phaseacc), sin(phaseacc) ); z = in * cmplx( cos(phaseacc), sin(phaseacc) );
phaseacc -= TWOPI * f / samplerate; phaseacc -= TWOPI * f / samplerate;
if (phaseacc > TWOPI) phaseacc -= TWOPI; if (phaseacc < 0) phaseacc += TWOPI;
if (phaseacc < -TWOPI) phaseacc += TWOPI;
return z; return z;
} }
@ -918,10 +917,7 @@ void mfsk::sendsymbol(int sym)
for (int i = 0; i < symlen; i++) { for (int i = 0; i < symlen; i++) {
outbuf[i] = cos(phaseacc); outbuf[i] = cos(phaseacc);
phaseacc -= phaseincr; phaseacc -= phaseincr;
if (phaseacc > M_PI) if (phaseacc < 0) phaseacc += TWOPI;
phaseacc -= TWOPI;
else if (phaseacc < M_PI)
phaseacc += TWOPI;
} }
transmit (outbuf, symlen); transmit (outbuf, symlen);
} }
@ -994,8 +990,7 @@ void mfsk::sendpic(unsigned char *data, int len)
for (j = 0; j < TXspp; j++) { for (j = 0; j < TXspp; j++) {
*ptr++ = cos(phaseacc); *ptr++ = cos(phaseacc);
phaseacc += TWOPI * f / samplerate; phaseacc += TWOPI * f / samplerate;
if (phaseacc > M_PI) if (phaseacc > TWOPI) phaseacc -= TWOPI;
phaseacc -= 2.0 * M_PI;
} }
} }
@ -1011,8 +1006,7 @@ void mfsk::flush_xmt_filter(int n)
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
outbuf[i] = cos(phaseacc); outbuf[i] = cos(phaseacc);
phaseacc += TWOPI * (reverse ? f2 : f1) / samplerate; phaseacc += TWOPI * (reverse ? f2 : f1) / samplerate;
if (phaseacc > M_PI) if (phaseacc > TWOPI) phaseacc -= TWOPI;
phaseacc -= 2.0 * M_PI;
} }
transmit (outbuf, tracepair.delay); transmit (outbuf, tracepair.delay);
} }

Wyświetl plik

@ -1023,8 +1023,7 @@ static double averageamp;
phase = arg ( conj(prevsymbol[car]) * symbol ); phase = arg ( conj(prevsymbol[car]) * symbol );
prevsymbol[car] = symbol; prevsymbol[car] = symbol;
if (phase < 0) if (phase < 0) phase += TWOPI;
phase += TWOPI;
if (_qpsk) { if (_qpsk) {
bits = ((int) (phase / M_PI_2 + 0.5)) & 3; bits = ((int) (phase / M_PI_2 + 0.5)) & 3;
@ -1207,8 +1206,7 @@ int psk::rx_process(const double *buf, int len)
z = cmplx ( *buf * cos(phaseacc[car]), *buf * sin(phaseacc[car]) ); z = cmplx ( *buf * cos(phaseacc[car]), *buf * sin(phaseacc[car]) );
phaseacc[car] += delta[car]; phaseacc[car] += delta[car];
if (phaseacc[car] > M_PI) if (phaseacc[car] > TWOPI) phaseacc[car] -= TWOPI;
phaseacc[car] -= TWOPI;
// Filter and downsample // Filter and downsample
// by 16 (psk31, qpsk31) // by 16 (psk31, qpsk31)
@ -1433,8 +1431,7 @@ void psk::tx_carriers()
} }
phaseacc[car] += delta[car]; phaseacc[car] += delta[car];
if (phaseacc[car] > M_PI) if (phaseacc[car] > TWOPI) phaseacc[car] -= TWOPI;
phaseacc[car] -= 2.0 * M_PI;
} }
prevsymbol[car] = symbol; prevsymbol[car] = symbol;

Wyświetl plik

@ -335,15 +335,11 @@ cmplx thor::mixer(int n, const cmplx& in)
else else
f = THORFIRSTIF - THORBASEFREQ - bandwidth*0.5 + (samplerate / symlen) * ( (double)n / paths); f = THORFIRSTIF - THORBASEFREQ - bandwidth*0.5 + (samplerate / symlen) * ( (double)n / paths);
double phase_n = phase[n]; cmplx z( cos(phase[n]), sin(phase[n]) );
cmplx z( cos(phase_n), sin(phase_n) );
z *= in; z *= in;
phase_n -= TWOPI * f / samplerate; phase[n] -= TWOPI * f / samplerate;
if (phase_n > M_PI) if (phase[n] < 0) phase[n] += TWOPI;
phase_n -= TWOPI;
else if (phase_n < M_PI)
phase_n += TWOPI;
phase[n] = phase_n;
return z; return z;
} }
@ -957,10 +953,7 @@ void thor::sendtone(int tone, int duration)
for (int i = 0; i < symlen; i++) { for (int i = 0; i < symlen; i++) {
outbuf[i] = cos(txphase); outbuf[i] = cos(txphase);
txphase -= phaseincr; txphase -= phaseincr;
if (txphase > M_PI) if (txphase < 0) txphase += TWOPI;
txphase -= TWOPI;
else if (txphase < M_PI)
txphase += TWOPI;
} }
ModulateXmtr(outbuf, symlen); ModulateXmtr(outbuf, symlen);
} }

Wyświetl plik

@ -280,10 +280,7 @@ cmplx throb::mixer(cmplx in)
phaseacc -= 2.0 * M_PI * f / THROB_SAMPLE_RATE; phaseacc -= 2.0 * M_PI * f / THROB_SAMPLE_RATE;
if (phaseacc < -M_PI) if (phaseacc < 0) phaseacc += TWOPI;
phaseacc += 2.0 * M_PI;
if (phaseacc > M_PI)
phaseacc -= 2.0 * M_PI;
return z; return z;
} }

Wyświetl plik

@ -336,8 +336,7 @@ void modem::set_samplerate(int smprate)
double modem::PTTnco() double modem::PTTnco()
{ {
PTTphaseacc += TWOPI * 1000 / samplerate; PTTphaseacc += TWOPI * 1000 / samplerate;
if (PTTphaseacc > M_PI) if (PTTphaseacc > TWOPI) PTTphaseacc -= TWOPI;
PTTphaseacc -= TWOPI;
return sin(PTTphaseacc); return sin(PTTphaseacc);
} }
@ -579,8 +578,7 @@ double modem::cwid_nco(double freq)
{ {
cwid_phaseacc += 2.0 * M_PI * freq / samplerate; cwid_phaseacc += 2.0 * M_PI * freq / samplerate;
if (cwid_phaseacc > M_PI) if (cwid_phaseacc > TWOPI) cwid_phaseacc -= TWOPI;
cwid_phaseacc -= 2.0 * M_PI;
return sin(cwid_phaseacc); return sin(cwid_phaseacc);
} }
@ -806,7 +804,7 @@ void modem::pretone()
for (int j = 0; j < symlen; j++) { for (int j = 0; j < symlen; j++) {
outbuf[j] = (0.5 * (1.0 - cos (M_PI * j / symlen)))*sin(phase); outbuf[j] = (0.5 * (1.0 - cos (M_PI * j / symlen)))*sin(phase);
phase += phaseincr; phase += phaseincr;
if (phase > 2.0 * M_PI) phase -= 2.0 * M_PI; if (phase > TWOPI) phase -= TWOPI;
} }
ModulateXmtr(outbuf, symlen); ModulateXmtr(outbuf, symlen);
@ -814,7 +812,7 @@ void modem::pretone()
for (int j = 0; j < symlen; j++) { for (int j = 0; j < symlen; j++) {
outbuf[j] = sin(phase); outbuf[j] = sin(phase);
phase += phaseincr; phase += phaseincr;
if (phase > 2.0 * M_PI) phase -= 2.0 * M_PI; if (phase > TWOPI) phase -= TWOPI;
} }
ModulateXmtr(outbuf, symlen); ModulateXmtr(outbuf, symlen);
} }
@ -822,7 +820,7 @@ void modem::pretone()
for (int j = 0; j < symlen; j++) { for (int j = 0; j < symlen; j++) {
outbuf[j] = (0.5 * (1.0 - cos (M_PI * (symlen - j) / symlen)))*sin(phase); outbuf[j] = (0.5 * (1.0 - cos (M_PI * (symlen - j) / symlen)))*sin(phase);
phase += phaseincr; phase += phaseincr;
if (phase > 2.0 * M_PI) phase -= 2.0 * M_PI; if (phase > TWOPI) phase -= TWOPI;
} }
ModulateXmtr(outbuf, symlen); ModulateXmtr(outbuf, symlen);

Wyświetl plik

@ -79,8 +79,7 @@ double outbuf[BUFLEN];
inline double nco() inline double nco()
{ {
phaseacc += phaseincr; phaseacc += phaseincr;
if (phaseacc > M_PI) if (phaseacc > TWOPI) phaseacc -= TWOPI;
phaseacc -= 2.0 * M_PI;
return cos(phaseacc); return cos(phaseacc);
} }

Wyświetl plik

@ -147,10 +147,7 @@ cmplx anal::mixer(cmplx in)
cmplx z = cmplx( cos(phaseacc), sin(phaseacc)) * in; cmplx z = cmplx( cos(phaseacc), sin(phaseacc)) * in;
phaseacc -= TWOPI * frequency / samplerate; phaseacc -= TWOPI * frequency / samplerate;
if (phaseacc > M_PI) if (phaseacc < 0) phaseacc += TWOPI;
phaseacc -= TWOPI;
else if (phaseacc < M_PI)
phaseacc += TWOPI;
return z; return z;
} }
@ -197,7 +194,7 @@ int anal::rx_process(const double *buf, int len)
// create analytic signal from sound card input samples // create analytic signal from sound card input samples
z = cmplx( *buf, *buf ); z = cmplx( *buf, *buf );
buf++; buf++;
hilbert->run(z, z); // hilbert->run(z, z);
// mix it with the audio carrier frequency to create a baseband signal // mix it with the audio carrier frequency to create a baseband signal
z = mixer(z); z = mixer(z);
// low pass filter using Windowed Sinc - Overlap-Add convolution filter // low pass filter using Windowed Sinc - Overlap-Add convolution filter

Wyświetl plik

@ -135,8 +135,7 @@ int wwv::rx_process(const double *buf, int len)
z = znco * z; z = znco * z;
phaseacc += phaseincr; phaseacc += phaseincr;
if (phaseacc > M_PI) if (phaseacc > TWOPI) phaseacc -= TWOPI;
phaseacc -= 2.0 * M_PI;
if (lpfilter->run ( z, z )) { if (lpfilter->run ( z, z )) {
buffer[smpl_ctr % 1000] = vidfilter->run( abs(z) ); buffer[smpl_ctr % 1000] = vidfilter->run( abs(z) );