comparison src/recpt1.c @ 168:061ef2cd98f0

Code refactoring.
author Naoya OYAMA <naoya.oyama@gmail.com>
date Sun, 07 Oct 2012 00:37:10 +0900
parents 726fe10d9e4a
children 4f3640bf350d
comparison
equal deleted inserted replaced
167:b21f1e823ec3 168:061ef2cd98f0
39 #include "pt1_common.h" 39 #include "pt1_common.h"
40 40
41 /* maximum write length at once */ 41 /* maximum write length at once */
42 #define SIZE_CHANK 1316 42 #define SIZE_CHANK 1316
43 43
44 #define ISDB_T_NODE_LIMIT 24 // 32:ARIB limit 24:program maximum
45 #define ISDB_T_SLOT_LIMIT 8
46
47 /* globals */ 44 /* globals */
48 boolean f_exit = FALSE; 45 boolean f_exit = FALSE;
49 struct channel_info_list *channel_list = NULL; 46 struct channel_info_list *channel_list = NULL;
50 extern struct ushare_t *ut; 47 extern struct ushare_t *ut;
51 char bs_channel_buf[8]; 48 thread_data *gp_tdata;
52 ISDB_T_FREQ_CONV_TABLE isdb_t_conv_set = { 0, CHTYPE_SATELLITE, 0, bs_channel_buf };
53 49
54 /* prototypes */ 50 /* prototypes */
55 int tune(char *channel, thread_data *tdata, char *device);
56 int close_tuner(thread_data *tdata);
57 static int get_device_id_by_name ( const char *name ); 51 static int get_device_id_by_name ( const char *name );
58 void calc_cn(int fd, int type);
59 ISDB_T_FREQ_CONV_TABLE *searchrecoff(char *channel);
60 52
61 static struct channel_info_list *open_list_file( 53 static struct channel_info_list *open_list_file(
62 char *type, 54 char *type,
63 struct channel_info_list *info_list) 55 struct channel_info_list *info_list)
64 { 56 {
260 if(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) { 252 if(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) {
261 fprintf(stderr, "Cannot tune to the specified channel\n"); 253 fprintf(stderr, "Cannot tune to the specified channel\n");
262 tdata->ch[0] = '\0'; 254 tdata->ch[0] = '\0';
263 goto CHECK_TIME_TO_ADD; 255 goto CHECK_TIME_TO_ADD;
264 } 256 }
265 calc_cn(tdata->tfd, tdata->table->type); 257 calc_cn(tdata->tfd, tdata->table->type, false);
266 } 258 }
267 /* restart recording */ 259 /* restart recording */
268 if(ioctl(tdata->tfd, START_REC, 0) < 0) { 260 if(ioctl(tdata->tfd, START_REC, 0) < 0) {
269 fprintf(stderr, "Tuner cannot start recording\n"); 261 fprintf(stderr, "Tuner cannot start recording\n");
270 return NULL; 262 return NULL;
290 } 282 }
291 } 283 }
292 if(f_exit) 284 if(f_exit)
293 return NULL; 285 return NULL;
294 } 286 }
295 }
296
297
298 /* lookup frequency conversion table*/
299 ISDB_T_FREQ_CONV_TABLE *
300 searchrecoff(char *channel)
301 {
302 int lp;
303
304 if((channel[0] == 'B' || channel[0] == 'b') &&
305 (channel[1] == 'S' || channel[1] == 's')) {
306 int node = 0;
307 int slot = 0;
308 char *bs_ch;
309
310 bs_ch = channel + 2;
311 while(isdigit(*bs_ch)) {
312 node *= 10;
313 node += *bs_ch++ - '0';
314 }
315 if(*bs_ch == '_' && (node&0x01) && node < ISDB_T_NODE_LIMIT) {
316 if(isdigit(*++bs_ch)) {
317 slot = *bs_ch - '0';
318 if(*++bs_ch == '\0' && slot < ISDB_T_SLOT_LIMIT) {
319 isdb_t_conv_set.set_freq = node / 2;
320 isdb_t_conv_set.add_freq = slot;
321 sprintf(bs_channel_buf, "BS%d_%d", node, slot);
322 return &isdb_t_conv_set;
323 }
324 }
325 }
326 return NULL;
327 }
328
329 for(lp = 0; isdb_t_conv_table[lp].parm_freq != NULL; lp++) {
330 /* return entry number in the table when strings match and
331 * lengths are same. */
332 if((memcmp(isdb_t_conv_table[lp].parm_freq, channel,
333 strlen(channel)) == 0) &&
334 (strlen(channel) == strlen(isdb_t_conv_table[lp].parm_freq))) {
335 return &isdb_t_conv_table[lp];
336 }
337 }
338 return NULL;
339 } 287 }
340 288
341 QUEUE_T * 289 QUEUE_T *
342 create_queue(size_t size) 290 create_queue(size_t size)
343 { 291 {
951 fprintf(stderr, "--version: Show version\n"); 899 fprintf(stderr, "--version: Show version\n");
952 fprintf(stderr, "--list: Show channel list\n"); 900 fprintf(stderr, "--list: Show channel list\n");
953 } 901 }
954 902
955 void 903 void
956 show_channels(void)
957 {
958 FILE *f;
959 char *home;
960 char buf[255], filename[255];
961
962 fprintf(stderr, "Available Channels:\n");
963
964 home = getenv("HOME");
965 sprintf(filename, "%s/.recpt1-channels", home);
966 f = fopen(filename, "r");
967 if(f) {
968 while(fgets(buf, 255, f))
969 fprintf(stderr, "%s", buf);
970 fclose(f);
971 }
972 else {
973 fprintf(stderr, "13-62: Terrestrial Channels\n");
974 fprintf(stderr, "101ch: NHK BS1\n");
975 fprintf(stderr, "102ch: NHK BS2\n");
976 fprintf(stderr, "103ch: NHK BShi\n");
977 fprintf(stderr, "141ch: BS Nittele\n");
978 fprintf(stderr, "151ch: BS Asahi\n");
979 fprintf(stderr, "161ch: BS-TBS\n");
980 fprintf(stderr, "171ch: BS Japan\n");
981 fprintf(stderr, "181ch: BS Fuji\n");
982 fprintf(stderr, "191ch: WOWOW\n");
983 fprintf(stderr, "192ch: WOWOW2\n");
984 fprintf(stderr, "193ch: WOWOW3\n");
985 fprintf(stderr, "200ch: Star Channel\n");
986 fprintf(stderr, "211ch: BS11 Digital\n");
987 fprintf(stderr, "222ch: TwellV\n");
988 fprintf(stderr, "C13-C63: CATV Channels\n");
989 fprintf(stderr, "CS2-CS24: CS Channels\n");
990 }
991 }
992
993 float
994 getsignal_isdb_s(int signal)
995 {
996 /* apply linear interpolation */
997 static const float afLevelTable[] = {
998 24.07f, // 00 00 0 24.07dB
999 24.07f, // 10 00 4096 24.07dB
1000 18.61f, // 20 00 8192 18.61dB
1001 15.21f, // 30 00 12288 15.21dB
1002 12.50f, // 40 00 16384 12.50dB
1003 10.19f, // 50 00 20480 10.19dB
1004 8.140f, // 60 00 24576 8.140dB
1005 6.270f, // 70 00 28672 6.270dB
1006 4.550f, // 80 00 32768 4.550dB
1007 3.730f, // 88 00 34816 3.730dB
1008 3.630f, // 88 FF 35071 3.630dB
1009 2.940f, // 90 00 36864 2.940dB
1010 1.420f, // A0 00 40960 1.420dB
1011 0.000f // B0 00 45056 -0.01dB
1012 };
1013
1014 unsigned char sigbuf[4];
1015 memset(sigbuf, '\0', sizeof(sigbuf));
1016 sigbuf[0] = (((signal & 0xFF00) >> 8) & 0XFF);
1017 sigbuf[1] = (signal & 0xFF);
1018
1019 /* calculate signal level */
1020 if(sigbuf[0] <= 0x10U) {
1021 /* clipped maximum */
1022 return 24.07f;
1023 }
1024 else if (sigbuf[0] >= 0xB0U) {
1025 /* clipped minimum */
1026 return 0.0f;
1027 }
1028 else {
1029 /* linear interpolation */
1030 const float fMixRate =
1031 (float)(((unsigned short)(sigbuf[0] & 0x0FU) << 8) |
1032 (unsigned short)sigbuf[0]) / 4096.0f;
1033 return afLevelTable[sigbuf[0] >> 4] * (1.0f - fMixRate) +
1034 afLevelTable[(sigbuf[0] >> 4) + 0x01U] * fMixRate;
1035 }
1036 }
1037
1038 void
1039 calc_cn(int fd, int type)
1040 {
1041 int rc ;
1042 double P ;
1043 double CNR;
1044
1045 if(ioctl(fd, GET_SIGNAL_STRENGTH, &rc) < 0) {
1046 fprintf(stderr, "Tuner Select Error\n");
1047 return ;
1048 }
1049
1050 if(type == CHTYPE_GROUND) {
1051 P = log10(5505024/(double)rc) * 10;
1052 CNR = (0.000024 * P * P * P * P) - (0.0016 * P * P * P) +
1053 (0.0398 * P * P) + (0.5491 * P)+3.0965;
1054 fprintf(stderr, "C/N = %fdB\n", CNR);
1055 }
1056 else {
1057 CNR = getsignal_isdb_s(rc);
1058 fprintf(stderr, "C/N = %fdB\n", CNR);
1059 }
1060 }
1061
1062 void
1063 cleanup(thread_data *tdata) 904 cleanup(thread_data *tdata)
1064 { 905 {
1065 boolean use_dlna = tdata->streamer ? TRUE : FALSE; 906 boolean use_dlna = tdata->streamer ? TRUE : FALSE;
1066 /* stop recording */ 907 /* stop recording */
1067 ioctl(tdata->tfd, STOP_REC, 0); 908 ioctl(tdata->tfd, STOP_REC, 0);
1135 976
1136 pthread_create(signal_thread, NULL, process_signals, tdata); 977 pthread_create(signal_thread, NULL, process_signals, tdata);
1137 } 978 }
1138 979
1139 int 980 int
1140 tune(char *channel, thread_data *tdata, char *device)
1141 {
1142 char **tuner;
1143 int num_devs;
1144 int lp;
1145 FREQUENCY freq;
1146
1147 /* get channel */
1148 tdata->table = searchrecoff(channel);
1149 if(tdata->table == NULL) {
1150 fprintf(stderr, "Invalid Channel: %s\n", channel);
1151 return 1;
1152 }
1153
1154 freq.frequencyno = tdata->table->set_freq;
1155 freq.slot = tdata->table->add_freq;
1156
1157 /* open tuner */
1158 /* case 1: specified tuner device */
1159 if(device) {
1160 tdata->tfd = open(device, O_RDONLY);
1161 tdata->device_id = get_device_id_by_name(device);
1162 if(tdata->tfd < 0) {
1163 fprintf(stderr, "Cannot open tuner device: %s\n", device);
1164 return 1;
1165 }
1166
1167 /* power on LNB */
1168 if(tdata->table->type == CHTYPE_SATELLITE) {
1169 if(ioctl(tdata->tfd, LNB_ENABLE, tdata->lnb) < 0) {
1170 fprintf(stderr, "Power on LNB failed: %s\n", device);
1171 }
1172 }
1173
1174 /* tune to specified channel */
1175 if(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) {
1176 close(tdata->tfd);
1177 fprintf(stderr, "Cannot tune to the specified channel: %s\n", device);
1178 return 1;
1179 }
1180 else {
1181 strncpy(tdata->ch, channel, sizeof(tdata->ch));
1182 }
1183 }
1184 else {
1185 /* case 2: loop around available devices */
1186 if(tdata->table->type == CHTYPE_SATELLITE) {
1187 tuner = bsdev;
1188 num_devs = NUM_BSDEV;
1189 }
1190 else {
1191 tuner = isdb_t_dev;
1192 num_devs = NUM_ISDB_T_DEV;
1193 }
1194
1195 for(lp = 0; lp < num_devs; lp++) {
1196 tdata->tfd = open(tuner[lp], O_RDONLY);
1197 if(tdata->tfd >= 0) {
1198 /* power on LNB */
1199 if(tdata->table->type == CHTYPE_SATELLITE) {
1200 if(ioctl(tdata->tfd, LNB_ENABLE, tdata->lnb) < 0) {
1201 fprintf(stderr, "Warning: Power on LNB failed: %s\n", tuner[lp]);
1202 }
1203 }
1204
1205 /* tune to specified channel */
1206 if(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) {
1207 close(tdata->tfd);
1208 tdata->tfd = -1;
1209 continue;
1210 }
1211
1212 tdata->device_id = get_device_id_by_name(tuner[lp]);
1213 break; /* found suitable tuner */
1214 }
1215 }
1216
1217 /* all tuners cannot be used */
1218 if(tdata->tfd < 0) {
1219 fprintf(stderr, "Cannot tune to the specified channel\n");
1220 return 1;
1221 }
1222 else {
1223 strncpy(tdata->ch, channel, sizeof(tdata->ch));
1224 }
1225 }
1226
1227 /* show signal strength */
1228 calc_cn(tdata->tfd, tdata->table->type);
1229
1230 return 0; /* success */
1231 }
1232
1233 int
1234 parse_time(char *rectimestr, thread_data *tdata) 981 parse_time(char *rectimestr, thread_data *tdata)
1235 { 982 {
1236 /* indefinite */ 983 /* indefinite */
1237 if(!strcmp("-", rectimestr)) { 984 if(!strcmp("-", rectimestr)) {
1238 tdata->indefinite = TRUE; 985 tdata->indefinite = TRUE;
1281 } 1028 }
1282 1029
1283 return 0; /* success */ 1030 return 0; /* success */
1284 } 1031 }
1285 1032
1286 int
1287 close_tuner(thread_data *tdata)
1288 {
1289 int rv = 0;
1290
1291 if(tdata->table->type == CHTYPE_SATELLITE) {
1292 if(ioctl(tdata->tfd, LNB_DISABLE, 0) < 0) {
1293 rv = 1;
1294 }
1295 }
1296 close(tdata->tfd);
1297
1298 return rv;
1299 }
1300
1301 thread_data *gp_tdata;
1302 1033
1303 int 1034 int
1304 main(int argc, char **argv) 1035 main(int argc, char **argv)
1305 { 1036 {
1306 time_t cur_time; 1037 time_t cur_time;