void HighPassFIR::newKernel (int32_t Fc) { int16_t i; DSPFLOAT tmp [filterSize]; DSPFLOAT f = (DSPFLOAT)Fc / sampleRate; DSPFLOAT sum = 0.0; for (i = 0; i < filterSize; i ++) { if (i == filterSize / 2) tmp [i] = 2 * M_PI * f; else tmp [i] = sin (2 * M_PI * f * (i - filterSize/2))/ (i - filterSize/2); tmp [i] *= (0.42 - 0.5 * cos (2 * M_PI * (DSPFLOAT)i / (DSPFLOAT)filterSize) + 0.08 * cos (4 * M_PI * (DSPFLOAT)i / (DSPFLOAT)filterSize)); sum += tmp [i]; } for (i = 0; i < filterSize; i ++) if (i == filterSize / 2) filterKernel [i] = DSPCOMPLEX (1.0 - tmp [i] / sum, 0); else filterKernel [i] = DSPCOMPLEX (- tmp [i] / sum, 0); }
// // Scaling p from 16000 -> 48000 is simple, juast add zeros and filter void audioSink::audioOut_16000 (int16_t *V, int32_t amount) { float *buffer = (float *)alloca (6 * amount * sizeof (float)); int32_t i; int32_t available = _O_Buffer -> GetRingBufferWriteAvailable (); amount = 3 * amount; if (2 * amount > available) amount = (available / 2) & ~01; for (i = 0; i < amount / 3; i ++) { DSPCOMPLEX help = DSPCOMPLEX (0, 0); help = DSPCOMPLEX (float (V [2 * i]) / 32767.0, float (V [2 * i + 1]) / 32767.0); help = f_16000 -> Pass (help); buffer [6 * i] = real (help); buffer [6 * i + 1] = imag (help); help = f_16000 -> Pass (DSPCOMPLEX (0, 0)); buffer [6 * i + 2] = real (help); buffer [6 * i + 3] = imag (help); help = f_16000 -> Pass (DSPCOMPLEX (0, 0)); buffer [6 * i + 4] = real (help); buffer [6 * i + 5] = imag (help); } if (dumpFile != NULL) sf_writef_float (dumpFile, buffer, amount); _O_Buffer -> putDataIntoBuffer (buffer, 2 * amount); }
/** * \class phaseReference * Implements the correlation that is used to identify * the "first" element (following the cyclic prefix) of * the first non-null block of a frame * The class inherits from the phaseTable. */ phaseReference::phaseReference (DabParams *p, int16_t blockSize, int16_t threshold): phaseTable (p -> dabMode) { int32_t i; DSPFLOAT Phi_k; this -> Tu = p -> T_u; this -> blockSize = blockSize; if (blockSize > Tu) blockSize = Tu; this -> threshold = threshold; Max = 0.0; refTable = new DSPCOMPLEX [Tu]; // fft_processor = new common_fft (Tu); fft_buffer = fft_processor -> getVector (); res_processor = new common_ifft (Tu); res_buffer = res_processor -> getVector (); fft_counter = 0; memset (refTable, 0, sizeof (DSPCOMPLEX) * Tu); for (i = 1; i <= p -> K / 2; i ++) { Phi_k = get_Phi (i); refTable [i] = DSPCOMPLEX (cos (Phi_k), sin (Phi_k)); Phi_k = get_Phi (-i); refTable [Tu - i] = DSPCOMPLEX (cos (Phi_k), sin (Phi_k)); } }
// // Conversion from 32 -> 48 is by first converting to 96000 // and then back to 48000 void audioSink::audioOut_32000 (int16_t *V, int32_t amount) { DSPCOMPLEX *buffer_1 = (DSPCOMPLEX *)alloca (3 * amount * sizeof (DSPCOMPLEX)); float *buffer = (float *)alloca (2 * 3 * amount / 2 * sizeof (float)); int32_t i; for (i = 0; i < amount; i ++) { DSPCOMPLEX help = DSPCOMPLEX (float (V [2 * i]) / 32767.0, float (V [2 * i + 1]) / 32767.0); buffer_1 [3 * i + 0] = f_32000 -> Pass (help); buffer_1 [3 * i + 1] = f_32000 -> Pass (DSPCOMPLEX (0, 0)); buffer_1 [3 * i + 2] = f_32000 -> Pass (DSPCOMPLEX (0, 0)); } // // Note that although we use "2 * i" for index left and right // they mean different things for (i = 0; i < 3 * amount / 2; i ++) { buffer [2 * i] = real (buffer_1 [2 * i]); buffer [2 * i + 1] = imag (buffer_1 [2 * i]); } if (dumpFile != NULL) sf_writef_float (dumpFile, buffer, 3 * amount / 2); _O_Buffer -> putDataIntoBuffer (buffer, 3 * amount); }
DSPCOMPLEX makeSample_15bits (uint8_t *buf) { int ii = 0; int qq = 0; int16_t i = 0; ii = (int)((unsigned char)(buf[i++])); ii += (int)((unsigned char)(buf[i++])) << 8; qq = (int)((unsigned char)(buf[i++])); qq += (int)((unsigned char)(buf[i++])) << 8; return DSPCOMPLEX ((float)ii / SCALE_FACTOR_14, (float)ii / SCALE_FACTOR_14); return DSPCOMPLEX ((float)qq / SCALE_FACTOR_14, (float)ii / SCALE_FACTOR_14); }
void DecimatingFIR::newKernel (int32_t low, int32_t high) { DSPFLOAT *tmp = (DSPFLOAT *)alloca (filterSize * sizeof (DSPFLOAT)); DSPFLOAT lo = (DSPFLOAT)((high - low) / 2) / sampleRate; DSPFLOAT shift = (DSPFLOAT) ((high + low) / 2) / sampleRate; DSPFLOAT sum = 0.0; int16_t i; for (i = 0; i < filterSize; i ++) { if (i == filterSize / 2) tmp [i] = 2 * M_PI * lo; else tmp [i] = sin (2 * M_PI * lo * (i - filterSize /2)) / (i - filterSize/2); // // windowing tmp [i] *= (0.42 - 0.5 * cos (2 * M_PI * (DSPFLOAT)i / (DSPFLOAT)filterSize) + 0.08 * cos (4 * M_PI * (DSPFLOAT)i / (DSPFLOAT)filterSize)); sum += tmp [i]; } // // and modulate the kernel for (i = 0; i < filterSize; i ++) { // shifting DSPFLOAT v = (i - filterSize / 2) * (2 * M_PI * shift); filterKernel [i] = DSPCOMPLEX (tmp [i] * cos (v) / sum, tmp [i] * sin (v) / sum); } }
// // For the kernel we compute the size of the "equivalent" // low pass filter (lo), and the amount of the shift void BandPassFIR::newKernel (int32_t low, int32_t high) { DSPFLOAT tmp [filterSize]; DSPFLOAT lo = (DSPFLOAT)((high - low) / 2) / sampleRate; DSPFLOAT shift = (DSPFLOAT) ((high + low) / 2) / sampleRate; DSPFLOAT sum = 0.0; int16_t i; for (i = 0; i < filterSize; i ++) { if (i == filterSize / 2) tmp [i] = 2 * M_PI * lo; else tmp [i] = sin (2 * M_PI * lo * (i - filterSize /2)) / (i - filterSize/2); // // windowing, according to Blackman tmp [i] *= (0.42 - 0.5 * cos (2 * M_PI * (DSPFLOAT)i / (DSPFLOAT)filterSize) + 0.08 * cos (4 * M_PI * (DSPFLOAT)i / (DSPFLOAT)filterSize)); sum += tmp [i]; } for (i = 0; i < filterSize; i ++) { // shifting DSPFLOAT v = (i - filterSize / 2) * (2 * M_PI * shift); filterKernel [i] = DSPCOMPLEX (tmp [i] * cos (v) / sum, tmp [i] * sin (v) / sum); } }
void reader_float::processData (float IQoffs, void *data, int cnt) { int32_t i; DSPCOMPLEX temp [blockSize]; float *p = (float *)data; (void)IQoffs; for (i = 0; i < blockSize; i ++) temp [i] = DSPCOMPLEX (p [2 * i], p [2 * i + 1]); theBuffer -> putDataIntoBuffer (temp, blockSize); }
Oscillator::Oscillator (int32_t rate) { int32_t i; Rate = rate; OscillatorValues = new DSPCOMPLEX [rate]; for (i = 0; i < rate; i ++) OscillatorValues [i] = DSPCOMPLEX (cos (2.0 * M_PI * i / rate), sin (2.0 * M_PI * i / rate)); LOPhase = 0; localTable = true; }
// // The brave old getSamples. For the dab stick, we get // size: still in I/Q pairs, but we have to convert the data from // uint8_t to DSPCOMPLEX * int32_t dabStick::getSamples (DSPCOMPLEX *V, int32_t size) { int32_t amount, i; uint8_t *tempBuffer = (uint8_t *)alloca (2 * size * sizeof (uint8_t)); // amount = _I_Buffer -> getDataFromBuffer (tempBuffer, 2 * size); for (i = 0; i < amount / 2; i ++) V [i] = DSPCOMPLEX ((float (tempBuffer [2 * i] - 128)) / 128.0, (float (tempBuffer [2 * i + 1] - 128)) / 128.0); return amount / 2; }
// // The brave old getSamples. For the mirics stick, we get // size still in I/Q pairs // Note that the sdrPlay returns 10 bit values int32_t sdrplay::getSamples (DSPCOMPLEX *V, int32_t size) { int32_t amount, i; int16_t *buf = (int16_t *)alloca (2 * size * sizeof (int16_t)); // amount = _I_Buffer -> getDataFromBuffer (buf, 2 * size); for (i = 0; i < amount / 2; i ++) V [i] = DSPCOMPLEX (buf [2 * i] / 2048.0, buf [2 * i + 1] / 2048.0); return amount / 2; }
SinCos::SinCos (int32_t Rate) { int32_t i; this -> Rate = Rate; this -> localTable = true; this -> Table = new DSPCOMPLEX [Rate]; for (i = 0; i < Rate; i ++) Table [i] = DSPCOMPLEX (cos (2 * M_PI * i / Rate), sin (2 * M_PI * i / Rate)); this -> C = Rate / (2 * M_PI); }
DSPCOMPLEX makeSample_30bits (uint8_t *buf) { int ii = 0; int qq = 0; int16_t i = 0; uint8_t q0 = buf [i++]; uint8_t q1 = buf [i++]; uint8_t q2 = buf [i++]; uint8_t q3 = buf [i++]; uint8_t i0 = buf [i++]; uint8_t i1 = buf [i++]; uint8_t i2 = buf [i++]; uint8_t i3 = buf [i++]; ii = (i3 << 24) | (i2 << 16) | (i1 << 8) | i0; qq = (q3 << 24) | (q2 << 16) | (q1 << 8) | q0; return DSPCOMPLEX ((float)ii / SCALE_FACTOR_29, (float)qq / SCALE_FACTOR_29); return DSPCOMPLEX ((float)ii / SCALE_FACTOR_29, (float)qq / SCALE_FACTOR_29); }
BasicBandPass::BasicBandPass (int16_t firsize, int32_t low, int32_t high, int32_t rate):Basic_FIR (firsize) { DSPFLOAT *t1 = (DSPFLOAT *)alloca (firsize * sizeof (DSPFLOAT)); int16_t i; t1 = BandPassKernel (t1, filterSize, (DSPFLOAT) low / rate, (DSPFLOAT) high / rate); for (i = 0; i < filterSize; i ++) filterKernel [i] = DSPCOMPLEX (t1 [i], t1 [i]); }
// called from AIRSPY data callback // this method is declared in airspyHandler class // The buffer received from hardware contains // 32-bit floating point IQ samples (8 bytes per sample) // // recoded for the sdr-j framework // 4*2 = 8 bytes for sample, as per AirSpy USB data stream format // we do the rate conversion here, read in groups of 625 samples // and transform them into groups of 512 samples int airspyHandler::data_available (void *buf, int buf_size) { float *sbuf = (float *)buf; int nSamples = buf_size / (sizeof (float) * 2); DSPCOMPLEX temp [nSamples]; int32_t i; for (i = 0; i < nSamples; i ++) temp [i] = DSPCOMPLEX (sbuf [2 * i], sbuf [2 * i + 1]); theBuffer -> putDataIntoBuffer (temp, nSamples); return 0; }
bool DecimatingFIR::Pass (DSPFLOAT z, DSPFLOAT *z_out) { if (++decimationCounter < decimationFactor) { Buffer [ip] = DSPCOMPLEX (z, 0); ip = (ip + 1) % filterSize; return false; } decimationCounter = 0; *z_out = Basic_FIR::Pass (z); return true; }
void fmLevels::addItem (DSPFLOAT v) { int16_t i; DSPFLOAT p0 = 0; DSPFLOAT p1 = 0; DSPFLOAT p2 = 0; DSPFLOAT p3 = 0; DSPFLOAT p4 = 0; inputBuffer [bufferPointer] = v * Window [bufferPointer]; if (++ bufferPointer >= size) bufferPointer = 0; counter ++; if (counter <= Rate_in / freq) return; counter = 0; for (i = 0; i < size; i ++) { buffer [i] = DSPCOMPLEX (inputBuffer [(bufferPointer + i) % size], 0); } compute -> do_FFT (); p0 = (abs (buffer [2]) + abs (buffer [size - 2])) / 2; p1 = (0.5 * abs (buffer [pilotPoller - 1]) + abs (buffer [pilotPoller]) + 0.5 * abs (buffer [pilotPoller + 1])) / 2; p2 = (0.5 * abs (buffer [rdsPoller_a - 1]) + abs (buffer [rdsPoller_a]) + 0.5 * abs (buffer [rdsPoller_a + 1]) + 0.5 * abs (buffer [rdsPoller_b - 1]) + abs (buffer [rdsPoller_b]) + 0.5 * abs (buffer [rdsPoller_b + 1])) / 4; p3 = (0.5 * abs (buffer [pilotNoisePol_a - 1]) + abs (buffer [pilotNoisePol_a]) + 0.5 * abs (buffer [pilotNoisePol_a + 1]) + 0.5 * abs (buffer [pilotNoisePol_b - 1]) + abs (buffer [pilotNoisePol_b]) + 0.5 * abs (buffer [pilotNoisePol_b + 1])) / 4; p4 = (0.5 * abs (buffer [rdsNoisePol_a - 1]) + abs (buffer [rdsNoisePol_a]) + 0.5 * abs (buffer [rdsNoisePol_a + 1]) + 0.5 * abs (buffer [rdsNoisePol_b - 1]) + abs (buffer [rdsNoisePol_b]) + 0.5 * abs (buffer [rdsNoisePol_b + 1])) / 4; signalLevel = 0.5 * p0 + 0.5 * signalLevel; pilotLevel = 0.3 * p1 + 0.7 * pilotLevel; rdsLevel = 0.3 * p2 + 0.7 * rdsLevel; pilotNoiseLevel = 0.3 * p3 + 0.7 * pilotNoiseLevel; rdsNoiseLevel = 0.3 * p4 + 0.7 * rdsNoiseLevel; }
BasicBandPass::BasicBandPass (int16_t firsize, int32_t low, int32_t high, int32_t rate):Basic_FIR (firsize) { DSPFLOAT t1 [firsize]; int16_t i; sampleRate = rate; (void) BandPassKernel (t1, firsize, (DSPFLOAT) low / rate, (DSPFLOAT) high / rate); for (i = 0; i < filterSize; i ++) filterKernel [i] = DSPCOMPLEX (t1 [i], t1 [i]); }
// // Good old getSamples // Note: n * rateIn / rateOut might give a wrong answer. // Keep the brackets!! // int32_t dabStick::getSamples (DSPCOMPLEX *V, int32_t n, uint8_t Mode) { int32_t size = n * (inputRate / outputRate); uint8_t *buf = (uint8_t *)alloca (2 * size * sizeof (uint8_t)); int32_t i, index; if (!open || !libraryLoaded) return 0; // first step: get data from the buffer (void) _I_Buffer -> getDataFromBuffer (buf, 2 * size); for (i = 0, index = 0; i < size; i ++) { DSPCOMPLEX tmp = DSPCOMPLEX ((buf [2 * i] - 127.0) / 128.0, (buf [2 * i + 1] - 127.0) / 128.0); if (d_filter -> Pass (tmp, &tmp)) { switch (Mode) { default: case IandQ: V [index ++] = tmp; break; case QandI: V [index ++] = DSPCOMPLEX (imag (tmp), real (tmp)); break; case Q_Only: V [index ++] = DSPCOMPLEX (real (tmp), 0.0); break; case I_Only: V [index ++] = DSPCOMPLEX (imag (tmp), 0.0); break; } } } return index; }
/* * length is number of uints that we read. */ int32_t wavFiles::readBuffer (DSPCOMPLEX *data, int32_t length) { int32_t i, n; float temp [2 * length]; n = sf_readf_float (filePointer, temp, length); if (n < length) { sf_seek (filePointer, 0, SEEK_SET); fprintf (stderr, "End of file, restarting\n"); } for (i = 0; i < n; i ++) data [i] = DSPCOMPLEX (4 * temp [2 * i], 4 * temp [2 * i + 1]); return n & ~01; }
// // apparently bytes are read in from low byte to high byte void reader_16::processData (float IQoffs, void *data, int cnt) { int32_t i; DSPCOMPLEX temp [blockSize]; uint8_t *p = (uint8_t *)data; (void)IQoffs; for (i = 0; i < blockSize; i ++) { uint8_t r0 = p [4 * i]; uint8_t r1 = p [4 * i + 1]; uint8_t i0 = p [4 * i + 2]; uint8_t i1 = p [4 * i + 3]; int16_t re = (r1 << 8) | r0; int16_t im = (i1 << 8) | i0; temp [i] = DSPCOMPLEX (float (re) / float (base), float (im) / float (base)); } theBuffer -> putDataIntoBuffer (temp, blockSize); }
void reader_24::processData (float IQoffs, void *data, int cnt) { int32_t i; DSPCOMPLEX temp [blockSize]; uint8_t *p = (uint8_t *)data; (void)IQoffs; for (i = 0; i < blockSize; i ++) { uint8_t r0 = p [6 * i]; uint8_t r1 = p [6 * i + 1]; uint8_t r2 = p [6 * i + 2]; uint8_t i0 = p [6 * i + 3]; uint8_t i1 = p [6 * i + 4]; uint8_t i2 = p [6 * i + 5]; int32_t re = int32_t (uint32_t (r2 << 16 | r1 << 8 | r0)); int32_t im = int32_t (uint32_t (i2 << 16 | i1 << 8 | i0)); temp [i] = DSPCOMPLEX (float (re) / float (base), float (im) / float (base)); } theBuffer -> putDataIntoBuffer (temp, blockSize); }
DSPCOMPLEX HilbertFilter::Pass (DSPCOMPLEX z) { DSPCOMPLEX tmp = 0; DSPFLOAT re, im; int i; Buffer [ip] = z; ip = (ip + 1) % firsize; for (i = 0; i < firsize; i ++) { int16_t index = ip - i; if (index < 0) index += firsize; re = real (Buffer [index]); im = imag (Buffer [index]); tmp += DSPCOMPLEX (re * cosKernel [i], im * sinKernel [i]); } return tmp; }
// // size is in I/Q pairs, file contains 8 bits values int32_t rawFiles::getSamples (DSPCOMPLEX *V, int32_t size) { int32_t amount, i; uint8_t *temp = (uint8_t *)alloca (2 * size * sizeof (uint8_t)); if (filePointer == NULL) return 0; while ((int32_t)(_I_Buffer -> GetRingBufferReadAvailable ()) < 2 * size) if (readerPausing) usleep (100000); else msleep (100); amount = _I_Buffer -> getDataFromBuffer (temp, 2 * size); for (i = 0; i < amount / 2; i ++) V [i] = DSPCOMPLEX (float (temp [2 * i] - 128) / 128.0, float (temp [2 * i + 1] - 128) / 128.0); return amount / 2; }
// Make a "downRate" times down sampled complex prototype tone for rx. DSPCOMPLEX *throb::mk_rxtone (float freq, int16_t len, int16_t downrate) { float baseTone; DSPCOMPLEX *tone; // the output vector double x; int16_t i; tone = new DSPCOMPLEX [len / downrate + 1]; for (i = 0; i < len; i += downrate) { baseTone = 0.5 * (1 - cos (2 * M_PI * i / (len / 2))); // // modulate with the frequency x = -2.0 * M_PI * freq * i / sampleRate; tone [i / downrate] = DSPCOMPLEX (baseTone * cos(x), baseTone * sin(x)); } return tone; }
void DecimatingFIR::newKernel (int32_t low) { int16_t i; DSPFLOAT *tmp = (DSPFLOAT *)alloca (filterSize * sizeof (DSPFLOAT)); DSPFLOAT f = (DSPFLOAT)low / sampleRate; DSPFLOAT sum = 0.0; for (i = 0; i < filterSize; i ++) { if (i == filterSize / 2) tmp [i] = 2 * M_PI * f; else tmp [i] = sin (2 * M_PI * f * (i - filterSize/2))/ (i - filterSize/2); tmp [i] *= (0.42 - 0.5 * cos (2 * M_PI * (DSPFLOAT)i / (DSPFLOAT)filterSize) + 0.08 * cos (4 * M_PI * (DSPFLOAT)i / (DSPFLOAT)filterSize)); sum += tmp [i]; } for (i = 0; i < filterSize; i ++) filterKernel [i] = DSPCOMPLEX (tmp [i] / sum, 0); }
void LowPassFIR::newKernel (int32_t Fc) { int16_t i; DSPFLOAT *tmp = (DSPFLOAT *)alloca (filterSize * sizeof (DSPFLOAT)); DSPFLOAT f = (DSPFLOAT)Fc / sampleRate; DSPFLOAT sum = 0.0; for (i = 0; i < filterSize; i ++) { if (i == filterSize / 2) tmp [i] = 2 * M_PI * f; else tmp [i] = sin (2 * M_PI * f * (i - filterSize/2))/ (i - filterSize/2); // // Blackman window tmp [i] *= (0.42 - 0.5 * cos (2 * M_PI * (DSPFLOAT)i / (DSPFLOAT)filterSize) + 0.08 * cos (4 * M_PI * (DSPFLOAT)i / (DSPFLOAT)filterSize)); sum += tmp [i]; } for (i = 0; i < filterSize; i ++) filterKernel [i] = DSPCOMPLEX (tmp [i] / sum, 0); }
int32_t eladHandler::getSamples (DSPCOMPLEX *V, int32_t size, uint8_t Mode) { int32_t amount, i; uint8_t buf [iqSize * size]; if (!deviceOK) return 0; amount = _I_Buffer -> getDataFromBuffer (buf, iqSize * size); for (i = 0; i < amount / iqSize; i ++) { switch (conversionNumber) { case 1: default: V [i] = cmul (makeSample_31bits (&buf [iqSize * i]), attenuation / 100.0); break; case 2: V [i] = cmul (makeSample_30bits (&buf [iqSize * i]), attenuation / 100.0); break; case 3: V [i] = cmul (makeSample_15bits (&buf [iqSize * i]), attenuation / 100.0); break; } switch (Mode) { default: case IandQ: break; case QandI: V [i] = DSPCOMPLEX (imag (V [i]), real (V [i])); break; } } return amount / iqSize; }
// // support functions // static inline DSPCOMPLEX valueFor (DSPFLOAT amp, int16_t phase) { return DSPCOMPLEX (amp * cos (2 * M_PI * phase / 1024), amp * sin (2 * M_PI * phase / 1024)); }
DSPCOMPLEX HilbertFilter::Pass (DSPFLOAT a, DSPFLOAT b) { return Pass (DSPCOMPLEX (a, b)); }