ModemKit *ModemFMStereo::buildKit(long long sampleRate, int audioSampleRate) { ModemKitFMStereo *kit = new ModemKitFMStereo; kit->audioResampleRatio = double(audioSampleRate) / double(sampleRate); kit->sampleRate = sampleRate; kit->audioSampleRate = audioSampleRate; float As = 60.0f; // stop-band attenuation [dB] kit->audioResampler = msresamp_rrrf_create(kit->audioResampleRatio, As); kit->stereoResampler = msresamp_rrrf_create(kit->audioResampleRatio, As); // Stereo filters / shifters double firStereoCutoff = 16000.0 / double(audioSampleRate); // filter transition float ft = 1000.0f / double(audioSampleRate); // fractional timing offset float mu = 0.0f; if (firStereoCutoff < 0) { firStereoCutoff = 0; } if (firStereoCutoff > 0.5) { firStereoCutoff = 0.5; } unsigned int h_len = estimate_req_filter_len(ft, As); float *h = new float[h_len]; liquid_firdes_kaiser(h_len, firStereoCutoff, As, mu, h); kit->firStereoLeft = firfilt_rrrf_create(h, h_len); kit->firStereoRight = firfilt_rrrf_create(h, h_len); // stereo pilot filter float bw = float(sampleRate); if (bw < 100000.0) { bw = 100000.0; } unsigned int order = 5; // filter order float f0 = ((float) 19000 / bw); float fc = ((float) 19500 / bw); float Ap = 1.0f; kit->iirStereoPilot = iirfilt_crcf_create_prototype(LIQUID_IIRDES_CHEBY2, LIQUID_IIRDES_BANDPASS, LIQUID_IIRDES_SOS, order, fc, f0, Ap, As); kit->firStereoR2C = firhilbf_create(5, 60.0f); kit->firStereoC2R = firhilbf_create(5, 60.0f); kit->stereoPilot = nco_crcf_create(LIQUID_VCO); nco_crcf_reset(kit->stereoPilot); nco_crcf_pll_set_bandwidth(kit->stereoPilot, 0.25f); return kit; }
void DemodulatorPreThread::initialize() { initialized = false; iqResampleRatio = (double) (params.bandwidth) / (double) params.sampleRate; audioResampleRatio = (double) (params.audioSampleRate) / (double) params.bandwidth; float As = 120.0f; // stop-band attenuation [dB] iqResampler = msresamp_crcf_create(iqResampleRatio, As); audioResampler = msresamp_rrrf_create(audioResampleRatio, As); stereoResampler = msresamp_rrrf_create(audioResampleRatio, As); // Stereo filters / shifters double firStereoCutoff = ((double) 16000 / (double) params.audioSampleRate); float ft = ((double) 1000 / (double) params.audioSampleRate); // filter transition float mu = 0.0f; // fractional timing offset if (firStereoCutoff < 0) { firStereoCutoff = 0; } if (firStereoCutoff > 0.5) { firStereoCutoff = 0.5; } unsigned int h_len = estimate_req_filter_len(ft, As); float *h = new float[h_len]; liquid_firdes_kaiser(h_len, firStereoCutoff, As, mu, h); firStereoLeft = firfilt_rrrf_create(h, h_len); firStereoRight = firfilt_rrrf_create(h, h_len); // stereo pilot filter float bw = params.bandwidth; if (bw < 100000.0) { bw = 100000.0; } unsigned int order = 5; // filter order float f0 = ((double) 19000 / bw); float fc = ((double) 19500 / bw); float Ap = 1.0f; As = 60.0f; iirStereoPilot = iirfilt_crcf_create_prototype(LIQUID_IIRDES_CHEBY2, LIQUID_IIRDES_BANDPASS, LIQUID_IIRDES_SOS, order, fc, f0, Ap, As); initialized = true; lastParams = params; }
int main() { // options unsigned int order=4; // filter order float fc=0.1f; // cutoff frequency float f0=0.25f; // center frequency (bandpass|bandstop) float Ap=1.0f; // pass-band ripple [dB] float As=40.0f; // stop-band attenuation [dB] liquid_iirdes_filtertype ftype = LIQUID_IIRDES_ELLIP; liquid_iirdes_bandtype btype = LIQUID_IIRDES_BANDPASS; liquid_iirdes_format format = LIQUID_IIRDES_SOS; // CREATE filter object (and print to stdout) iirfilt_crcf myfilter; myfilter = iirfilt_crcf_create_prototype(ftype, btype, format, order, fc, f0, Ap, As); iirfilt_crcf_print(myfilter); // allocate memory for data arrays unsigned int n=128; // number of samples float complex x[n]; // input samples array float complex y[n]; // output samples array // run filter unsigned int i; for (i=0; i<n; i++) { // initialize input x[i] = randnf() + _Complex_I*randnf(); // EXECUTE filter (repeat as many times as desired) iirfilt_crcf_execute(myfilter, x[i], &y[i]); } // DESTROY filter object iirfilt_crcf_destroy(myfilter); }
void DemodulatorWorkerThread::threadMain() { std::cout << "Demodulator worker thread started.." << std::endl; while (!terminated) { bool filterChanged = false; DemodulatorWorkerThreadCommand filterCommand; DemodulatorWorkerThreadCommand command; bool done = false; while (!done) { commandQueue->pop(command); switch (command.cmd) { case DemodulatorWorkerThreadCommand::DEMOD_WORKER_THREAD_CMD_BUILD_FILTERS: filterChanged = true; filterCommand = command; break; default: break; } done = commandQueue->empty(); } if (filterChanged && !terminated) { DemodulatorWorkerThreadResult result(DemodulatorWorkerThreadResult::DEMOD_WORKER_THREAD_RESULT_FILTERS); float As = 60.0f; // stop-band attenuation [dB] if (filterCommand.sampleRate && filterCommand.bandwidth) { result.iqResampleRatio = (double) (filterCommand.bandwidth) / (double) filterCommand.sampleRate; result.iqResampler = msresamp_crcf_create(result.iqResampleRatio, As); } if (filterCommand.bandwidth && filterCommand.audioSampleRate) { result.audioResamplerRatio = (double) (filterCommand.audioSampleRate) / (double) filterCommand.bandwidth; result.audioResampler = msresamp_rrrf_create(result.audioResamplerRatio, As); result.stereoResampler = msresamp_rrrf_create(result.audioResamplerRatio, As); result.audioSampleRate = filterCommand.audioSampleRate; // Stereo filters / shifters double firStereoCutoff = ((double) 16000 / (double) filterCommand.audioSampleRate); float ft = ((double) 1000 / (double) filterCommand.audioSampleRate); // filter transition float mu = 0.0f; // fractional timing offset if (firStereoCutoff < 0) { firStereoCutoff = 0; } if (firStereoCutoff > 0.5) { firStereoCutoff = 0.5; } unsigned int h_len = estimate_req_filter_len(ft, As); float *h = new float[h_len]; liquid_firdes_kaiser(h_len, firStereoCutoff, As, mu, h); result.firStereoLeft = firfilt_rrrf_create(h, h_len); result.firStereoRight = firfilt_rrrf_create(h, h_len); float bw = filterCommand.bandwidth; if (bw < 100000.0) { bw = 100000.0; } // stereo pilot filter unsigned int order = 5; // filter order float f0 = ((double) 19000 / bw); float fc = ((double) 19500 / bw); float Ap = 1.0f; As = 60.0f; result.iirStereoPilot = iirfilt_crcf_create_prototype(LIQUID_IIRDES_CHEBY2, LIQUID_IIRDES_BANDPASS, LIQUID_IIRDES_SOS, order, fc, f0, Ap, As); } if (filterCommand.bandwidth) { result.bandwidth = filterCommand.bandwidth; } if (filterCommand.sampleRate) { result.sampleRate = filterCommand.sampleRate; } resultQueue->push(result); } } std::cout << "Demodulator worker thread done." << std::endl; }