--- dvbstream/tune.c.opt~ 2003-02-07 19:26:44.000000000 +0100 +++ dvbstream/tune.c 2003-02-07 19:37:13.000000000 +0100 @@ -21,6 +21,7 @@ #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <ctype.h> #include <sys/ioctl.h> #include <sys/poll.h> @@ -39,6 +40,19 @@ #include "tune.h" +#ifndef __cplusplus +typedef char bool; +#define true 1 +#define false 0 +#endif + +struct dvb_status { + bool ok; /* Could tune in */ + uint32_t ber; /* Bit error rate */ + uint16_t strength; /* Signal strength */ + uint16_t snr; /* Signal/Noise ratio */ +}; + #ifndef NEWSTRUCT int OSTSelftest(int fd) { @@ -168,18 +182,20 @@ } #ifdef NEWSTRUCT -int check_status(int fd_frontend,struct dvb_frontend_parameters* feparams,int tone) { +struct dvb_status check_status(int fd_frontend,struct dvb_frontend_parameters* feparams,int tone) { int i,res; - int32_t strength; fe_status_t festatus; struct dvb_frontend_event event; struct dvb_frontend_info fe_info; + struct dvb_status result; struct pollfd pfd[1]; int status; + memset(&result, 0, sizeof(struct dvb_status)); + if (ioctl(fd_frontend,FE_SET_FRONTEND,feparams) < 0) { perror("ERROR tuning channel\n"); - return -1; + return result; } pfd[0].fd = fd_frontend; @@ -194,7 +210,7 @@ if (status = ioctl(fd_frontend, FE_GET_EVENT, &event) < 0){ if (status != -EOVERFLOW) { perror("FE_GET_EVENT"); - return -1; + return result; } } } @@ -222,41 +238,41 @@ break; } - strength=0; - ioctl(fd_frontend,FE_READ_BER,&strength); - fprintf(stderr,"Bit error rate: %d\n",strength); - - strength=0; - ioctl(fd_frontend,FE_READ_SIGNAL_STRENGTH,&strength); - fprintf(stderr,"Signal strength: %d\n",strength); - - strength=0; - ioctl(fd_frontend,FE_READ_SNR,&strength); - fprintf(stderr,"SNR: %d\n",strength); + ioctl(fd_frontend,FE_READ_BER,&result.ber); + fprintf(stderr,"Bit error rate: %d\n",result.ber); + + ioctl(fd_frontend,FE_READ_SIGNAL_STRENGTH,&result.strength); + fprintf(stderr,"Signal strength: %d\n",result.strength); + + ioctl(fd_frontend,FE_READ_SNR,&result.snr); + fprintf(stderr,"SNR: %d\n",result.snr); festatus=0; ioctl(fd_frontend,FE_READ_STATUS,&festatus); print_status(stderr,festatus); + + result.ok=true; } else { fprintf(stderr,"Not able to lock to the signal on the given frequency\n"); - return -1; + return result; } - return 0; + return result; } #else -int check_status(int fd_frontend,FrontendParameters* feparams,int tone) { +struct dvb_status check_status(int fd_frontend,FrontendParameters* feparams,int tone) { int i,res; - int32_t strength; fe_status_t festatus; FrontendEvent event; FrontendInfo fe_info; struct pollfd pfd[1]; + struct dvb_status result; + memset(&result, 0, sizeof(struct dvb_status)); i = 0; res = -1; while ((i < 3) && (res < 0)) { if (ioctl(fd_frontend,FE_SET_FRONTEND,feparams) < 0) { perror("ERROR tuning channel\n"); - return -1; + return result; } pfd[0].fd = fd_frontend; @@ -267,7 +283,7 @@ fprintf(stderr,"Getting frontend event\n"); if ( ioctl(fd_frontend, FE_GET_EVENT, &event) < 0) { perror("FE_GET_EVENT"); - return -1; + return result; } fprintf(stderr,"Received "); switch(event.type){ @@ -319,17 +335,14 @@ break; } - strength=0; - ioctl(fd_frontend,FE_READ_BER,&strength); - fprintf(stderr,"Bit error rate: %d\n",strength); - - strength=0; - ioctl(fd_frontend,FE_READ_SIGNAL_STRENGTH,&strength); - fprintf(stderr,"Signal strength: %d\n",strength); - - strength=0; - ioctl(fd_frontend,FE_READ_SNR,&strength); - fprintf(stderr,"SNR: %d\n",strength); + ioctl(fd_frontend,FE_READ_BER,&result.ber); + fprintf(stderr,"Bit error rate: %d\n",result.ber); + + ioctl(fd_frontend,FE_READ_SIGNAL_STRENGTH,&result.strength); + fprintf(stderr,"Signal strength: %d\n",result.strength); + + ioctl(fd_frontend,FE_READ_SNR,&result.snr); + fprintf(stderr,"SNR: %d\n",result.snr); festatus=0; ioctl(fd_frontend,FE_READ_STATUS,&festatus); @@ -344,11 +357,12 @@ if (festatus & FE_HAS_SYNC) fprintf(stderr," FE_HAS_SYNC"); if (festatus & FE_TUNER_HAS_LOCK) fprintf(stderr," FE_TUNER_HAS_LOCK"); fprintf(stderr,"\n"); + result.ok=true; } else { fprintf(stderr,"Not able to lock to the signal on the given frequency\n"); - return -1; + return result; } - return 0; + return result; } #endif @@ -383,9 +397,221 @@ } #endif +unsigned int optimize(int fd_frontend, int fd_sec, unsigned int basefreq, unsigned int srate, char pol, int tone, fe_spectral_inversion_t specInv, unsigned int diseqc, fe_modulation_t modulation, fe_code_rate_t HP_CodeRate, fe_transmit_mode_t TransmissionMode, fe_guard_interval_t guardInterval, fe_bandwidth_t bandwidth) { + int res; + int tries=0; + struct dvb_status ret; + unsigned int start=0, end=0; + int ber_ok=0; +#ifdef NEWSTRUCT + struct dvb_frontend_parameters feparams; + struct dvb_frontend_info fe_info; + fe_sec_voltage_t voltage; +#else + FrontendParameters feparams; + FrontendInfo fe_info; + secVoltage voltage; + struct secStatus sec_state; +#endif + + unsigned int freq; + for(freq=basefreq-11000; !end && freq<basefreq+11000; freq+=200) { + if ( (res = ioctl(fd_frontend,FE_GET_INFO, &fe_info) < 0)){ + perror("FE_GET_INFO: "); + return -1; + } + +#ifdef NEWSTRUCT + fprintf(stderr,"Using DVB card \"%s\"\n",fe_info.name); +#endif + + switch(fe_info.type) { + case FE_OFDM: +#ifdef NEWSTRUCT + if (freq < 1000000) freq*=1000UL; + feparams.frequency=freq; + feparams.inversion=INVERSION_OFF; + feparams.u.ofdm.bandwidth=bandwidth; + feparams.u.ofdm.code_rate_HP=HP_CodeRate; + feparams.u.ofdm.code_rate_LP=LP_CODERATE_DEFAULT; + feparams.u.ofdm.constellation=modulation; + feparams.u.ofdm.transmission_mode=TransmissionMode; + feparams.u.ofdm.guard_interval=guardInterval; + feparams.u.ofdm.hierarchy_information=HIERARCHY_DEFAULT; +#else + if (freq < 1000000) freq*=1000UL; + feparams.Frequency=freq; + feparams.Inversion=INVERSION_OFF; + feparams.u.ofdm.bandWidth=bandwidth; + feparams.u.ofdm.HP_CodeRate=HP_CodeRate; + feparams.u.ofdm.LP_CodeRate=LP_CODERATE_DEFAULT; + feparams.u.ofdm.Constellation=modulation; + feparams.u.ofdm.TransmissionMode=TransmissionMode; + feparams.u.ofdm.guardInterval=guardInterval; + feparams.u.ofdm.HierarchyInformation=HIERARCHY_DEFAULT; +#endif + fprintf(stderr,"tuning DVB-T (%s) to %d Hz\n",DVB_T_LOCATION,freq); + break; + case FE_QPSK: +#ifdef NEWSTRUCT + fprintf(stderr,"tuning DVB-S to L-Band:%d, Pol:%c Srate=%d, 22kHz=%s\n",feparams.frequency,pol,srate,tone == SEC_TONE_ON ? "on" : "off"); +#else + fprintf(stderr,"tuning DVB-S to L-Band:%d, Pol:%c Srate=%d, 22kHz=%s\n",feparams.Frequency,pol,srate,tone == SEC_TONE_ON ? "on" : "off"); +#endif + if ((pol=='h') || (pol=='H')) { + voltage = SEC_VOLTAGE_18; + } else { + voltage = SEC_VOLTAGE_13; + } +#ifdef NEWSTRUCT + if (ioctl(fd_frontend,FE_SET_VOLTAGE,voltage) < 0) { +#else + if (ioctl(fd_sec,SEC_SET_VOLTAGE,voltage) < 0) { +#endif + perror("ERROR setting voltage\n"); + } + + if (freq > 2200000) { + // this must be an absolute frequency + if (freq < SLOF) { +#ifdef NEWSTRUCT + feparams.frequency=(freq-LOF1); +#else + feparams.Frequency=(freq-LOF1); +#endif + if (tone < 0) tone = SEC_TONE_OFF; + } else { +#ifdef NEWSTRUCT + feparams.frequency=(freq-LOF2); +#else + feparams.Frequency=(freq-LOF2); +#endif + if (tone < 0) tone = SEC_TONE_ON; + } + } else { + // this is an L-Band frequency +#ifdef NEWSTRUCT + feparams.frequency=freq; +#else + feparams.Frequency=freq; +#endif + } + +#ifdef NEWSTRUCT + feparams.inversion=specInv; + feparams.u.qpsk.symbol_rate=srate; + feparams.u.qpsk.fec_inner=FEC_AUTO; +#else + feparams.Inversion=specInv; + feparams.u.qpsk.SymbolRate=srate; + feparams.u.qpsk.FEC_inner=FEC_AUTO; +#endif + +#ifdef NEWSTRUCT + if (ioctl(fd_frontend,FE_SET_TONE,tone) < 0) { + perror("ERROR setting tone\n"); + } +#else + if (ioctl(fd_sec,SEC_SET_TONE,tone) < 0) { + perror("ERROR setting tone\n"); + } +#endif + +#ifdef NEWSTRUCT + if (diseqc > 0) + set_diseqc(fd_frontend, diseqc, voltage, tone); + else { + if (ioctl(fd_frontend, FE_SET_TONE, tone) < 0) + perror("ERROR setting tone:"); + } +#else + if (diseqc > 0) { + struct secCommand scmd; + struct secCmdSequence scmds; + + scmds.continuousTone = tone; + scmds.voltage = voltage; + /* + scmds.miniCommand = toneBurst ? SEC_MINI_B : SEC_MINI_A; + */ + scmds.miniCommand = SEC_MINI_NONE; + + scmd.type = 0; + scmds.numCommands = 1; + scmds.commands = &scmd; + + scmd.u.diseqc.addr = 0x10; + scmd.u.diseqc.cmd = 0x38; + scmd.u.diseqc.numParams = 1; + scmd.u.diseqc.params[0] = 0xf0 | + (((diseqc - 1) << 2) & 0x0c) | + (voltage==SEC_VOLTAGE_18 ? 0x02 : 0) | + (tone==SEC_TONE_ON ? 0x01 : 0); + + if (ioctl(fd_sec,SEC_SEND_SEQUENCE,&scmds) < 0) { + perror("Error sending DisEqC"); + return -1; + } + } +#endif + break; + case FE_QAM: + fprintf(stderr,"tuning DVB-C to %d, srate=%d\n",freq,srate); +#ifdef NEWSTRUCT + feparams.frequency=freq; + feparams.inversion=INVERSION_OFF; + feparams.u.qam.symbol_rate = srate; + feparams.u.qam.fec_inner = FEC_AUTO; + feparams.u.qam.modulation = QAM_64; +#else + feparams.Frequency=freq; + feparams.Inversion=INVERSION_OFF; + feparams.u.qam.SymbolRate = srate; + feparams.u.qam.FEC_inner = FEC_AUTO; + feparams.u.qam.QAM = QAM_64; +#endif + break; + default: + fprintf(stderr,"Unknown FE type. Aborting\n"); + exit(-1); + } + usleep(10000); + ret=check_status(fd_frontend,&feparams,tone); + if(ret.ok && ret.ber<ret.snr) { + if(ber_ok<0) + ber_ok=0; + else + ber_ok++; + if(!start && ber_ok==10) { + start=freq-10*200; + } + } else { + if(start) + end=freq; + ber_ok=0; + } + +#ifndef NEWSTRUCT + if (fd_sec) SecGetStatus(fd_sec, &sec_state); +#endif + } + + if(!start || !end) { + if(!start) + fprintf(stderr, "WARNING: No start found.\n"); + if(!end) + fprintf(stderr, "WARNING: No end found.\n"); + return basefreq; + } + fprintf(stderr, "start: %u, end: %u -> optimal frequency %u\n", start, end, (start+end)/2); + return (start+end)/2; +} + + int tune_it(int fd_frontend, int fd_sec, unsigned int freq, unsigned int srate, char pol, int tone, fe_spectral_inversion_t specInv, unsigned int diseqc,fe_modulation_t modulation,fe_code_rate_t HP_CodeRate,fe_transmit_mode_t TransmissionMode,fe_guard_interval_t guardInterval, fe_bandwidth_t bandwidth) { int res; - int tries=0, ret=0; + int tries=0; + struct dvb_status ret; #ifdef NEWSTRUCT struct dvb_frontend_parameters feparams; struct dvb_frontend_info fe_info; @@ -580,7 +806,7 @@ if (fd_sec) SecGetStatus(fd_sec, &sec_state); #endif tries++; - } while((ret=check_status(fd_frontend,&feparams,tone))<0 && tries<3); + } while(!(ret=check_status(fd_frontend,&feparams,tone)).ok && tries<3); - return ret; + return !(ret.ok); } --- dvbstream/dvbstream.c.opt~ 2003-02-07 19:26:44.000000000 +0100 +++ dvbstream/dvbstream.c 2003-02-07 19:26:44.000000000 +0100 @@ -536,6 +536,11 @@ instant_repack(buf+4+off, TS_SIZE-4-off, p); } +#ifndef __cplusplus +typedef char bool; +#define true 1 +#define false 0 +#endif int main(int argc, char **argv) { @@ -553,6 +558,7 @@ unsigned char* free_bytes; int output_type=RTP_TS; int exit_after_tuning=0; + bool do_optimize=false; /* Output: {uni,multi,broad}cast socket */ char ipOut[20]; @@ -585,6 +591,7 @@ fprintf(stderr,"-i IP multicast address\n"); fprintf(stderr,"-r IP multicast port\n"); fprintf(stderr,"-o Stream to stdout instead of network\n"); + fprintf(stderr,"-O Optimize a frequency\n"); fprintf(stderr,"-n secs Stop after secs seconds\n"); fprintf(stderr,"-ps Convert stream to Program Stream format (needs exactly 2 pids)\n"); fprintf(stderr,"-v vpid Decode video PID (full cards only)\n"); @@ -640,6 +647,8 @@ diseqc=atoi(argv[++i]); } else if (strcmp(argv[i],"-o")==0) { to_stdout = 1; + } else if (strcmp(argv[i],"-O")==0) { + do_optimize=true; } else if ((strcmp(argv[i],"-n")==0) || (strcmp(argv[i],"-t")==0)) { i++; secs=atoi(argv[i]); @@ -762,10 +771,14 @@ } } else if ((transponder_freq!=0) && (transponder_pol!=0) && (transponder_srate!=0)) { if (open_fe(&fd_frontend,&fd_sec)) { - i=tune_it(fd_frontend,fd_sec,transponder_freq,transponder_srate,transponder_pol,tone,specInv,diseqc,modulation,HP_CodeRate,TransmissionMode,guardInterval,bandWidth); + if(do_optimize) { + i=optimize(fd_frontend,fd_sec,transponder_freq,transponder_srate,transponder_pol,tone,specInv,diseqc,modulation,HP_CodeRate,TransmissionMode,guardInterval,bandWidth); + fprintf(stderr, "Optimized frequency: %u\n", i); + } else + i=tune_it(fd_frontend,fd_sec,transponder_freq,transponder_srate,transponder_pol,tone,specInv,diseqc,modulation,HP_CodeRate,TransmissionMode,guardInterval,bandWidth); close(fd_frontend); if (fd_sec) close(fd_sec); - if(exit_after_tuning) + if(exit_after_tuning || do_optimize) return 0; } } --- dvbstream/tune.h.opt~ 2002-10-13 20:46:03.000000000 +0200 +++ dvbstream/tune.h 2003-02-07 19:26:44.000000000 +0100 @@ -24,6 +24,7 @@ #include "dvb_defaults.h" +unsigned int optimize(int fd_frontend, int fd_sec, unsigned int freq, unsigned int srate, char pol, int tone, fe_spectral_inversion_t specInv, unsigned int diseqc,fe_modulation_t modulation,fe_code_rate_t HP_CodeRate,fe_transmit_mode_t TransmissionMode,fe_guard_interval_t guardInterval, fe_bandwidth_t bandwidth); int tune_it(int fd_frontend, int fd_sec, unsigned int freq, unsigned int srate, char pol, int tone, fe_spectral_inversion_t specInv, unsigned int diseqc,fe_modulation_t modulation,fe_code_rate_t HP_CodeRate,fe_transmit_mode_t TransmissionMode,fe_guard_interval_t guardInterval, fe_bandwidth_t bandwidth); #endif