static void *demod_thread_fn(void *arg) { while (!do_exit) { safe_cond_wait(&ready, &ready_m); pthread_rwlock_wrlock(&both.rw); downsample(&both); memcpy(left.buf, both.buf, 2*both.len_out); memcpy(right.buf, both.buf, 2*both.len_out); pthread_rwlock_unlock(&both.rw); rotate_90(left.buf, left.len_in); downsample(&left); memcpy(left_demod.buf, left.buf, 2*left.len_out); demodulate(&left_demod); if (dc_filter) { dc_block_filter(&left_demod);} //if (oversample) { // downsample(&left);} arbitrary_upsample(left_demod.result, stereo.buf_left, left_demod.result_len, stereo.bl_len); rotate_m90(right.buf, right.len_in); downsample(&right); memcpy(right_demod.buf, right.buf, 2*right.len_out); demodulate(&right_demod); if (dc_filter) { dc_block_filter(&right_demod);} //if (oversample) { // downsample(&right);} arbitrary_upsample(right_demod.result, stereo.buf_right, right_demod.result_len, stereo.br_len); output(); } rtlsdr_cancel_async(dev); return 0; }
void full_demod(struct fm_state *fm) { int i, sr, freq_next, hop = 0; // pthread_mutex_lock(&data_ready); static unsigned char tmpBuf[DEFAULT_BUF_LENGTH]; while(ringbuffer_is_empty((ringbuffer*)fm->buf)) { usleep(100000); } ringbuffer_read((ringbuffer*)fm->buf, tmpBuf); //fprintf(stderr, "data!\n"); rotate_90(tmpBuf, sizeof(tmpBuf)); if (fm->fir_enable) { low_pass_fir(fm, tmpBuf, sizeof(tmpBuf)); } else { low_pass(fm, tmpBuf, sizeof(tmpBuf)); } // pthread_mutex_unlock(&data_write); fm->mode_demod(fm); if (fm->mode_demod == &raw_demod) { fwrite(fm->signal2, 2, fm->signal2_len, fm->file); return; } sr = post_squelch(fm); if (!sr && fm->squelch_hits > fm->conseq_squelch) { if (fm->terminate_on_squelch) { fm->exit_flag = 1;} if (fm->freq_len == 1) { /* mute */ for (i=0; i<fm->signal_len; i++) { fm->signal2[i] = 0;} } else { hop = 1;} } if (fm->post_downsample > 1) { fm->signal2_len = low_pass_simple(fm->signal2, fm->signal2_len, fm->post_downsample);} if (fm->output_rate > 0) { low_pass_real(fm); } if (fm->deemph) { deemph_filter(fm);} if (fm->dc_block) { dc_block_filter(fm);} /* ignore under runs for now */ fwrite(fm->signal2, 2, fm->signal2_len, fm->file); if (hop && ringbuffer_is_empty((ringbuffer*)fm->buf)) { // Making sure the buffer is empty before tuning freq_next = (fm->freq_now + 1) % fm->freq_len; optimal_settings(fm, freq_next, 1); fm->squelch_hits = fm->conseq_squelch + 1; /* hair trigger */ /* wait for settling and flush buffer */ usleep(5000); rtlsdr_read_sync(dev, NULL, 4096, NULL); } }
void full_demod(struct fm_state *fm) { uint8_t dump[BUFFER_DUMP]; int i, sr, freq_next, n_read, hop = 0; pthread_rwlock_wrlock(&data_rw); rotate_90(fm->buf, fm->buf_len); if (fm->fir_enable) { low_pass_fir(fm, fm->buf, fm->buf_len); } else { low_pass(fm, fm->buf, fm->buf_len); } pthread_rwlock_unlock(&data_rw); fm->mode_demod(fm); if (fm->mode_demod == &raw_demod) { fwrite(fm->signal2, 2, fm->signal2_len, fm->file); return; } sr = post_squelch(fm); if (!sr && fm->squelch_hits > fm->conseq_squelch) { if (fm->terminate_on_squelch) { fm->exit_flag = 1;} if (fm->freq_len == 1) { /* mute */ for (i=0; i<fm->signal_len; i++) { fm->signal2[i] = 0;} } else { hop = 1;} } if (fm->post_downsample > 1) { fm->signal2_len = low_pass_simple(fm->signal2, fm->signal2_len, fm->post_downsample);} if (fm->output_rate > 0) { low_pass_real(fm); } if (fm->deemph) { deemph_filter(fm);} if (fm->dc_block) { dc_block_filter(fm);} /* ignore under runs for now */ fwrite(fm->signal2, 2, fm->signal2_len, fm->file); if (hop) { freq_next = (fm->freq_now + 1) % fm->freq_len; optimal_settings(fm, freq_next, 1); fm->squelch_hits = fm->conseq_squelch + 1; /* hair trigger */ /* wait for settling and flush buffer */ usleep(5000); rtlsdr_read_sync(dev, &dump, BUFFER_DUMP, &n_read); if (n_read != BUFFER_DUMP) { fprintf(stderr, "Error: bad retune.\n");} } }