static int cdx2834_init(struct dvb_frontend *fe) { struct cdx2834_state *state = fe->demodulator_priv; demod_init(state); msleep(200); return 0; }
int tune_single_tuner_and_demod_channel(struct dibTuner *tuner, struct dibDemod *demod, struct dibChannel *ch) { int time, ret; if (demod_init(demod) != 0) { DibDbgPrint("-E- Demod init failed\n"); return 1; } if (tuner_init(tuner) != 0) { DibDbgPrint("-E- Tuner init failed\n"); return 1; } if (tuner_set_bandwidth_ex(tuner, ch) != 0) { DibDbgPrint("-E- Tuner set_bandwidth failed\n"); return 1; } if (tuner_tune(tuner, ch) != 0) { DibDbgPrint("-E- Tuner tune_digital failed\n"); return 1; } /* prepare the agc startup loop */ demod_agc_restart(demod); do { time = -1; ret = demod_agc_startup_ex(demod, ch); if (ret > time) time = ret; if (time != -1) DibMSleep(time); } while (time != -1); if ((ch->type == STANDARD_DVBT && (ch->u.dvbt.nfft == FFT_AUTO || ch->u.dvbt.guard == GUARD_INTERVAL_AUTO || ch->u.dvbt.constellation == QAM_AUTO || ch->u.dvbt.intlv_native == INTLV_NATIVE_AUTO || ch->u.dvbt.hrch == VIT_HRCH_AUTO || ch->u.dvbt.select_hp == VIT_PRIORITY_AUTO || ch->u.dvbt.alpha == VIT_ALPHA_AUTO || ch->u.dvbt.code_rate_hp == VIT_CODERATE_AUTO || ((ch->u.dvbt.hrch == VIT_HRCH_ON && ch->u.dvbt.code_rate_lp == VIT_CODERATE_AUTO)))) || ((ch->type == STANDARD_ISDBT) && (ch->u.isdbt.nfft == FFT_AUTO || ch->u.isdbt.guard == GUARD_INTERVAL_AUTO))) if (single_do_autosearch(demod, ch) != 0) { DibDbgPrint("-W- autosearching parameters failed.\n"); return 1; } dump_dvb_channel_params(ch); if (demod_tune_ex(demod,ch) != 0){ DibDbgPrint("-W- tuning failed for demod - this is just a warning could be normal in diversity.\n"); return 1; } return 0; }
static int gx1001_init(struct dvb_frontend *fe) { struct gx1001_state *state = fe->demodulator_priv; //GX_Init_Chip(); pr_dbg("=========================demod init\r\n"); demod_init(state); msleep(200); return 0; }
int main(int argc, char **argv) { struct sigaction sigact; char *filename = NULL; int r, opt; int i, gain = AUTO_GAIN; /* tenths of a dB */ int dev_index = 0; int dev_given = 0; int ppm_error = 0; int custom_ppm = 0; int left_freq = 161975000; int right_freq = 162025000; int sample_rate = 12000; int output_rate = 48000; int dongle_freq, dongle_rate, delta; int edge = 0; pthread_cond_init(&ready, NULL); pthread_mutex_init(&ready_m, NULL); while ((opt = getopt(argc, argv, "l:r:s:o:EODd:g:p:h")) != -1) { switch (opt) { case 'l': left_freq = (int)atofs(optarg); break; case 'r': right_freq = (int)atofs(optarg); break; case 's': sample_rate = (int)atofs(optarg); break; case 'o': output_rate = (int)atofs(optarg); break; case 'E': edge = !edge; break; case 'D': dc_filter = !dc_filter; break; case 'O': oversample = !oversample; break; case 'd': dev_index = verbose_device_search(optarg); dev_given = 1; break; case 'g': gain = (int)(atof(optarg) * 10); break; case 'p': ppm_error = atoi(optarg); custom_ppm = 1; break; case 'h': default: usage(); return 2; } } if (argc <= optind) { filename = "-"; } else { filename = argv[optind]; } if (left_freq > right_freq) { usage(); return 2; } /* precompute rates */ dongle_freq = left_freq/2 + right_freq/2; if (edge) { dongle_freq -= sample_rate/2;} delta = right_freq - left_freq; if (delta > 1.2e6) { fprintf(stderr, "Frequencies may be at most 1.2MHz apart."); exit(1); } if (delta < 0) { fprintf(stderr, "Left channel must be lower than right channel."); exit(1); } i = (int)log2(2.4e6 / delta); dongle_rate = delta * (1<<i); both.rate_in = dongle_rate; both.rate_out = delta * 2; i = (int)log2(both.rate_in/both.rate_out); both.downsample_passes = i; both.downsample = 1 << i; left.rate_in = both.rate_out; i = (int)log2(left.rate_in / sample_rate); left.downsample_passes = i; left.downsample = 1 << i; left.rate_out = left.rate_in / left.downsample; right.rate_in = left.rate_in; right.rate_out = left.rate_out; right.downsample = left.downsample; right.downsample_passes = left.downsample_passes; if (left.rate_out > output_rate) { fprintf(stderr, "Channel bandwidth too high or output bandwidth too low."); exit(1); } stereo.rate = output_rate; if (edge) { fprintf(stderr, "Edge tuning enabled.\n"); } else { fprintf(stderr, "Edge tuning disabled.\n"); } if (dc_filter) { fprintf(stderr, "DC filter enabled.\n"); } else { fprintf(stderr, "DC filter disabled.\n"); } fprintf(stderr, "Buffer size: %0.2f mS\n", 1000 * (double)DEFAULT_BUF_LENGTH / (double)dongle_rate); fprintf(stderr, "Downsample factor: %i\n", both.downsample * left.downsample); fprintf(stderr, "Low pass: %i Hz\n", left.rate_out); fprintf(stderr, "Output: %i Hz\n", output_rate); /* precompute lengths */ both.len_in = DEFAULT_BUF_LENGTH; both.len_out = both.len_in / both.downsample; left.len_in = both.len_out; right.len_in = both.len_out; left.len_out = left.len_in / left.downsample; right.len_out = right.len_in / right.downsample; left_demod.buf_len = left.len_out; left_demod.result_len = left_demod.buf_len / 2; right_demod.buf_len = left_demod.buf_len; right_demod.result_len = left_demod.result_len; stereo.bl_len = (int)((long)(DEFAULT_BUF_LENGTH/2) * (long)output_rate / (long)dongle_rate); stereo.br_len = stereo.bl_len; stereo.result_len = stereo.br_len * 2; stereo.rate = output_rate; if (!dev_given) { dev_index = verbose_device_search("0"); } if (dev_index < 0) { exit(1); } downsample_init(&both); downsample_init(&left); downsample_init(&right); demod_init(&left_demod); demod_init(&right_demod); stereo_init(&stereo); r = rtlsdr_open(&dev, (uint32_t)dev_index); if (r < 0) { fprintf(stderr, "Failed to open rtlsdr device #%d.\n", dev_index); exit(1); } sigact.sa_handler = sighandler; sigemptyset(&sigact.sa_mask); sigact.sa_flags = 0; sigaction(SIGINT, &sigact, NULL); sigaction(SIGTERM, &sigact, NULL); sigaction(SIGQUIT, &sigact, NULL); sigaction(SIGPIPE, &sigact, NULL); if (strcmp(filename, "-") == 0) { /* Write samples to stdout */ file = stdout; setvbuf(stdout, NULL, _IONBF, 0); } else { file = fopen(filename, "wb"); if (!file) { fprintf(stderr, "Failed to open %s\n", filename); exit(1); } } /* Set the tuner gain */ if (gain == AUTO_GAIN) { verbose_auto_gain(dev); } else { gain = nearest_gain(dev, gain); verbose_gain_set(dev, gain); } if (!custom_ppm) { verbose_ppm_eeprom(dev, &ppm_error); } verbose_ppm_set(dev, ppm_error); //r = rtlsdr_set_agc_mode(dev, 1); /* Set the tuner frequency */ verbose_set_frequency(dev, dongle_freq); /* Set the sample rate */ verbose_set_sample_rate(dev, dongle_rate); /* Reset endpoint before we start reading from it (mandatory) */ verbose_reset_buffer(dev); pthread_create(&demod_thread, NULL, demod_thread_fn, (void *)(NULL)); rtlsdr_read_async(dev, rtlsdr_callback, (void *)(NULL), DEFAULT_ASYNC_BUF_NUMBER, DEFAULT_BUF_LENGTH); if (do_exit) { fprintf(stderr, "\nUser cancel, exiting...\n");} else { fprintf(stderr, "\nLibrary error %d, exiting...\n", r);} rtlsdr_cancel_async(dev); safe_cond_signal(&ready, &ready_m); pthread_cond_destroy(&ready); pthread_mutex_destroy(&ready_m); if (file != stdout) { fclose(file);} rtlsdr_close(dev); return r >= 0 ? r : -r; }
/* tune (do autosearch in case of unknown parameters) */ void tune_diversity_tuner_and_demod_channel(struct dibTuner *tuner[], struct dibDemod *demod[], int num, struct dibChannel *ch) { int i, time, ret; for (i = 0; i < num; i++) { if (demod_init(demod[i]) != 0) { DibDbgPrint("-E- Tuner init failed\n"); return; } if (tuner_init(tuner[i]) != 0) { DibDbgPrint("-E- Tuner init failed\n"); return; } } for (i = 0; i < num; i++) { if (tuner_set_bandwidth_ex(tuner[i], ch) != 0) { DibDbgPrint("-E- Tuner set_bandwidth failed\n"); return; } if (tuner_tune(tuner[i], ch) != 0) { DibDbgPrint("-E- Tuner tune_digital failed\n"); return; } /* prepare the agc startup loop */ demod_agc_restart(demod[i]); } do { time = -1; for (i = 0; i < num; i++) { ret = demod_agc_startup_ex(demod[i], ch); if (ret > time) time = ret; } if (time != -1) DibMSleep(time); } while (time != -1); if ((ch->type == STANDARD_DVBT && (ch->u.dvbt.nfft == FFT_AUTO || ch->u.dvbt.guard == GUARD_INTERVAL_AUTO || ch->u.dvbt.constellation == QAM_AUTO || ch->u.dvbt.intlv_native == INTLV_NATIVE_AUTO || ch->u.dvbt.hrch == VIT_HRCH_AUTO || ch->u.dvbt.select_hp == VIT_PRIORITY_AUTO || ch->u.dvbt.alpha == VIT_ALPHA_AUTO || ch->u.dvbt.code_rate_hp == VIT_CODERATE_AUTO || ((ch->u.dvbt.hrch == VIT_HRCH_ON && ch->u.dvbt.code_rate_lp == VIT_CODERATE_AUTO))))) if (do_autosearch(demod, num, ch) != 0) { DibDbgPrint("-W- autosearching parameters failed.\n"); return; } dump_dvb_channel_params(ch); for (i = 0; i < num; i++) { if (demod_tune_ex(demod[i],ch) != 0) DibDbgPrint("-W- tuning failed for demod - this is just a warning could be normal in diversity.\n"); } for (i = 0; i < num; i++) { if (i == num-1) { // last demod in a diversity chain - turn off div-in combination DibDbgPrint("-D- setting diversity in off for demod %d\n",i); demod_set_diversity_in(demod[i], 0); } else { DibDbgPrint("-D- setting diversity in on for demod %d\n",i); demod_set_diversity_in(demod[i], 1); } if (i == 0) { // first demod in a diversity chain - no diversity output DibDbgPrint("-D- setting normal output for demod %d\n",i); demod_set_output_mode(demod[i], OUTMODE_MPEG2_PAR_GATED_CLK); } else { DibDbgPrint("-D- setting diversity out on for demod %d\n",i); demod_set_output_mode(demod[i], OUTMODE_DIVERSITY); } } return; }
uint16_t frontend_get_isdbt_sb_channels(struct dibFrontend *fe[], uint32_t freq , uint32_t bw, int num, struct dibChannel ch[]) { uint16_t seg_bw_khz = 429; int16_t rf_offset_khz = 0; uint16_t total_segment_number = (uint16_t)((bw / seg_bw_khz) - 1); // 1 is the freq guard int segment_index = 0, channel_index = 0, subch_id = -1; int i; dbgpl(NULL, "will search SB on %d potential segment(s) inside a bandwidth of %dkhz arround FR freq %dkhz", total_segment_number, bw, freq); for (i = 0; i < num; i++) { if (demod_init(fe[i]) != 0) { DibDbgPrint("-E- Tuner init failed\n"); return 0; } if (tuner_init(fe[i]) != 0) { DibDbgPrint("-E- Tuner init failed\n"); return 0; } } for (segment_index = 1; segment_index <= total_segment_number; segment_index++) { int success, fe_fail_count; channel_init(&ch[channel_index], STANDARD_ISDBT); /* compute segment center freq */ rf_offset_khz = seg_bw_khz * (segment_index - (total_segment_number/2) - (total_segment_number%2)); dbgpl(NULL,"rf_offset_khz = %d",rf_offset_khz); /* add a half of seg BW offset is total number of connected seg is even */ if((total_segment_number%2) == 0) { dbgpl(NULL,"compensate for 1/2 seg (%d khz) tune freq because sb_conn_total_seg is even = %d",seg_bw_khz, total_segment_number); rf_offset_khz-=(seg_bw_khz/2); } dbgpl(NULL,"rf_offset_khz = %d",rf_offset_khz); ch[channel_index].RF_kHz = freq + rf_offset_khz; ch[channel_index].bandwidth_kHz = bw; ch[channel_index].u.isdbt.sb_mode = 1; if (subch_id != -1) subch_id += 3; ch[channel_index].u.isdbt.sb_subchannel = subch_id; dbgpl(NULL,"---------------------- Start search on segment #%d center freq = %dkhz (%d+%d, %d)--------------------- ", segment_index,ch[channel_index].RF_kHz, freq, rf_offset_khz, subch_id); for (i = 0; i < num; i++) frontend_tune_restart(fe[i], FE_RESTART_TUNE_PROCESS_FROM_TUNER, &ch[channel_index]); do { success = 0; fe_fail_count = 0; for (i = 0; i < num; i++) { frontend_tune(fe[i], &ch[channel_index]); if (fe[i]->status_has_changed && (frontend_get_status(fe[i]) == FE_STATUS_DEMOD_SUCCESS || frontend_get_status(fe[i]) == FE_STATUS_FFT_SUCCESS)) { //dbgpl(&adapter_dbg, "Autosearch succeeded on FE %d", fe[i]->id); frontend_get_channel(fe[i], &ch[channel_index]); /* we read the channel parameters from the frontend which was successful */ if (ch[channel_index].u.isdbt.partial_reception == 1) { ch[channel_index].bandwidth_kHz = seg_bw_khz * 3; /* bandwidth is for 3 segments */ segment_index++; /* no need to check the next segment */ } else ch[channel_index].bandwidth_kHz = seg_bw_khz; #ifdef DIBCOM_EXTENDED_MONITORING dump_digital_channel_params(&ch[channel_index]); #endif } if (frontend_get_status(fe[i]) == FE_STATUS_LOCKED) { subch_id = ch[channel_index].u.isdbt.sb_subchannel; channel_index++; success = 1; break; } else if(frontend_get_status(fe[i]) == FE_STATUS_TUNE_FAILED) { fe_fail_count++; } } } while (!success && fe_fail_count != num); if (success) DibDbgPrint("-I- Autosearch succeeded for demod %d channel_index = %d - done.\n",i, channel_index); else DibDbgPrint("-I- Autosearch failled for demod %d channel_index = %d - done. %d/%d\n",i, channel_index, fe_fail_count, num); } return channel_index; }
int start_the_radio(int device_index, long freq_hz, long output_SR, int gain_db10) { // post("inside start_the_radio()" ); // int err = 0; // tz for usage call int r; int dev_given = 0; // gets set on, if user passes in device index arg (-d) // int custom_ppm = 0; // gets set on, if users specifies freq correction arg (-p) char device_index_str[10] = "0"; // initialization dongle_init(&dongle); demod_init(&demod); output_init(&output); controller_init(&controller); buffer_init(); // tz reset index pointers // handle device index if(device_index != 0) { sprintf(device_index_str,"%d", device_index); dongle.dev_index = verbose_device_search(device_index_str); dev_given = 1; } // set gain // tz - note that when passing this param from Max/Pd it gets passed in // db * 10 format - so we don't need extra multiplier // this is done to allow setting to AUTOGAIN // dongle.gain = gain_db10 ; // set sample rate demod.rate_in = (uint32_t) output_SR; demod.rate_out = (uint32_t) output_SR; // set frequency controller.freqs[controller.freq_len] = (uint32_t) freq_hz; controller.freq_len++; // note: here is how dongle ppm error correction was set in rtl_fm // dongle.ppm_error = atoi(optarg); // custom_ppm = 1; // do initial setup // tz this was for resampling and can be removed output.rate = demod.rate_out; // tz this can get cleaned up too... // set buffer length - would need to increase if downsample rate increased // ACTUAL_BUF_LENGTH = DEFAULT_BUF_LENGTH; // if user specied a device number, use it - otherwise default to 0 if (!dev_given) { dongle.dev_index = verbose_device_search("0"); } if (dongle.dev_index < 0) { return(1); } // open device r = rtlsdr_open(&dongle.dev, (uint32_t)dongle.dev_index); if (r < 0) { // sprintf(errmesg, "Failed to open rtlsdr device #%d.\n", dongle.dev_index); sprintf(errmesg, "Failed to open rtlsdr device #%d.\n", dongle.dev_index); post(errmesg, 0); return(1); } set_tuner_gain(&dongle); // do freq error correction verbose_ppm_set(dongle.dev, dongle.ppm_error); //r = rtlsdr_set_testmode(dongle.dev, 1); /* Reset endpoint before we start reading from it (mandatory) */ verbose_reset_buffer(dongle.dev); // tz these threads all get running in parallel here // int errx; // for debugging - not really used now errx = pthread_create(&controller.thread, NULL, controller_thread_fn, (void *)(&controller)); usleep(100000); errx = pthread_create(&dongle.thread, NULL, dongle_thread_fn, (void *)(&dongle)); radio_running = 1; return(0); }