Mercurial > pt1.oyama
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; |