def animate_update(block_count, iq_data, block_size, rf_coeff, audio_coeff): global audio_data, state_i_lpf_100k, state_q_lpf_100k, state_phase if (block_count+1)*block_size > len(iq_data): print('Finished processing the raw I/Q samples') # write audio data to file (assumes audio_data samples are -1 to +1) wavfile.write("../data/fmMonoAnim.wav", int(audio_Fs), np.int16((audio_data/2)*32767)) sys.exit() # filter to extract the FM channel (I samples are even, Q samples are odd) i_filt, state_i_lpf_100k = signal.lfilter(rf_coeff, 1.0, \ iq_data[(block_count)*block_size:(block_count+1)*block_size:2], zi=state_i_lpf_100k) q_filt, state_q_lpf_100k = signal.lfilter(rf_coeff, 1.0, \ iq_data[(block_count)*block_size+1:(block_count+1)*block_size:2], zi=state_q_lpf_100k) # downsample the FM channel i_ds = i_filt[::rf_decim] q_ds = q_filt[::rf_decim] # FM demodulator fm_demod, state_phase = fmDemodArctan(i_ds, q_ds, state_phase) # PSD after FM demodulation ax0.clear() ax0.psd(fm_demod, NFFT=512, Fs=(rf_Fs/rf_decim)/1e3) # freq, my_psd = estimatePSD(fm_demod, NFFT=512, Fs=(rf_Fs/rf_decim)/1e3) # ax0.plot(freq, my_psd) ax0.set_ylabel('PSD (dB/Hz)') ax0.set_xlabel('Freq (kHz)') ax0.set_title('Demodulated FM (block ' + str(block_count) + ')')
def rf_frontend(): # coefficients for the front-end low-pass filter rf_coeff = signal.firwin(rf_taps, rf_Fc / (rf_Fs / 2), window=('hann')) # rf_coeff = lp_impulse(rf_Fc, rf_Fs, rf_taps) # filter to extract the FM channel (I samples are even, Q samples are odd) i_filt = signal.lfilter(rf_coeff, 1.0, iq_data[0::2]) q_filt = signal.lfilter(rf_coeff, 1.0, iq_data[1::2]) block_size = int(len(iq_data[0::2])) # print(block_size) # i_filt, buf_wave = conv(iq_data[0::2], rf_coeff, np.zeros(len(rf_coeff)-1)) # q_filt, buf_wave = conv(iq_data[1::2], rf_coeff, np.zeros(len(rf_coeff)-1)) # downsample the FM channel i_ds = i_filt[::rf_decim] q_ds = q_filt[::rf_decim] print("ARCTAN DEMOD BEGIN (LEN I = " + str(len(i_ds)) + ")") # FM demodulator (check the library) fm_demod = fmDemodArctan(i_ds, q_ds) print("ARCTAN DEMOD EMD") return fm_demod
print('Processing block ' + str(block_count)) # filter to extract the FM channel (I samples are even, Q samples are odd) i_filt, state_i_lpf_100k = signal.lfilter(rf_coeff, 1.0, \ iq_data[(block_count)*block_size:(block_count+1)*block_size:2], zi=state_i_lpf_100k) q_filt, state_q_lpf_100k = signal.lfilter(rf_coeff, 1.0, \ iq_data[(block_count)*block_size+1:(block_count+1)*block_size:2], zi=state_q_lpf_100k) # downsample the I/Q data from the FM channel i_ds = i_filt[::rf_decim] q_ds = q_filt[::rf_decim] # FM demodulator fm_demod, state_phase = fmDemodArctan(i_ds, q_ds, state_phase) tone_filt, state_tone = signal.lfilter(tone_pass_coeff, 1.0, \ fm_demod, zi=state_tone) stereo_filt, state_stereo = signal.lfilter(stereo_pass_coeff, 1.0, \ fm_demod, zi=state_stereo) ncoOut, state_integrator, state_phaseEst, state_feedbackI, state_feedbackQ, state_ncoOut0, state_trigOffset \ = fmPll(tone_filt,19e3,rf_Fs/rf_decim,ncoScale = 2, \
# rf_coeff = lp_impulse(rf_Fc, rf_Fs, rf_taps) # filter to extract the FM channel (I samples are even, Q samples are odd) i_filt = signal.lfilter(rf_coeff, 1.0, iq_data[0::2]) q_filt = signal.lfilter(rf_coeff, 1.0, iq_data[1::2]) block_size = int(len(iq_data[0::2])) # print(block_size) # i_filt, buf_wave = conv(iq_data[0::2], rf_coeff, np.zeros(len(rf_coeff)-1)) # q_filt, buf_wave = conv(iq_data[1::2], rf_coeff, np.zeros(len(rf_coeff)-1)) # downsample the FM channel i_ds = i_filt[::rf_decim] q_ds = q_filt[::rf_decim] # FM demodulator (check the library) fm_demod, buf_I, buf_Q = fmDemodArctan(i_ds, q_ds) # we use a dummy because there is no state for this single-pass model # set up drawing fig, (ax0, ax1, ax2) = plt.subplots(nrows=3) fig.subplots_adjust(hspace = 1.0) # PSD after FM demodulation ax0.psd(fm_demod, NFFT=512, Fs=(rf_Fs/rf_decim)/1e3) ax0.set_ylabel('PSD (db/Hz)') ax0.set_title('Demodulated FM') # coefficients for the filter to extract mono audio # audio_coeff = np.array([]) # to be updated by you during in-lab audio_coeff = signal.firwin(audio_taps, audio_Fc/(24e4/2), window=('hann')) # audio_coeff = lp_impulse(audio_Fc, 24e4, audio_taps)
zi=state_i_lpf_state) # q_filt, state_q_lpf_state = signal.lfilter(rf_coeff, 1.0, \ iq_data[(block_count)*block_size+1:(block_count+1)*block_size:2], zi=state_q_lpf_state) # i_filt, state_i_lpf_100k = conv(iq_data[(block_count)*block_size:(block_count+1)*block_size:2], rf_coeff, state_i_lpf_100k) # q_filt, state_q_lpf_100k = conv(iq_data[(block_count)*block_size+1:(block_count+1)*block_size:2], rf_coeff, state_q_lpf_100k) # downsample the FM channel i_ds = i_filt[::rf_decim] q_ds = q_filt[::rf_decim] # FM demodulator # fm_demod, state_phase = fmDemodArctan(i_ds, q_ds, state_phase) fm_demod, buf_I, buf_Q = fmDemodArctan(i_ds, q_ds, block_count, buf_I, buf_Q) # extract the mono audio data through filtering # audio_filt = ... change as needed mono_filt, mono_lpf_state = signal.lfilter(audio_coeff, 1.0, \ fm_demod, zi=mono_lpf_state) # audio_filt, mono_lpf_100k = conv(fm_demod, audio_coeff, mono_lpf_100k) # downsample audio data # audio_block = ... change as needed mono_block = mono_filt[::audio_decim] stereo_channel, stereo_channel_state = signal.lfilter( stereo_channel_coeff, 1.0, fm_demod, zi=stereo_channel_state)
iq_data = np.fromfile(in_fname, dtype='float32') print("Read raw RF data from \"" + in_fname + "\" in float32 format") # coefficients for the front-end low-pass filter rf_coeff = signal.firwin(rf_taps, rf_Fc / (rf_Fs / 2), window=('hann')) # filter to extract the FM channel (I samples are even, Q samples are odd) i_filt = signal.lfilter(rf_coeff, 1.0, iq_data[0::2]) q_filt = signal.lfilter(rf_coeff, 1.0, iq_data[1::2]) # downsample the FM channel i_ds = i_filt[::rf_decim] q_ds = q_filt[::rf_decim] # FM demodulator (check the library) fm_demod, dummy = fmDemodArctan(i_ds, q_ds) # we use a dummy because there is no state for this single-pass model # set up drawing fig, (ax0, ax1, ax2) = plt.subplots(nrows=3) fig.subplots_adjust(hspace=1.0) # PSD after FM demodulation ax0.psd(fm_demod, NFFT=512, Fs=(rf_Fs / rf_decim) / 1e3) ax0.set_ylabel('PSD (db/Hz)') ax0.set_title('Demodulated FM') # coefficients for the filter to extract mono audio audio_coeff = np.array([]) # to be updated by you during in-lab # extract the mono audtio data through filtering