Mercurial > pt1
comparison recpt1/recpt1core.c @ 140:c9b1d21c5035
separate common function to core library
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Thu, 25 Apr 2013 16:06:15 +0900 (2013-04-25) |
parents | |
children | c8688d7d6382 |
comparison
equal
deleted
inserted
replaced
139:61ff9cabf962 | 140:c9b1d21c5035 |
---|---|
1 #include <stdio.h> | |
2 #include <stdlib.h> | |
3 #include "recpt1core.h" | |
4 #include "version.h" | |
5 #include "pt1_dev.h" | |
6 | |
7 #define ISDB_T_NODE_LIMIT 24 // 32:ARIB limit 24:program maximum | |
8 #define ISDB_T_SLOT_LIMIT 8 | |
9 | |
10 /* globals */ | |
11 boolean f_exit = FALSE; | |
12 char bs_channel_buf[8]; | |
13 ISDB_T_FREQ_CONV_TABLE isdb_t_conv_set = { 0, CHTYPE_SATELLITE, 0, bs_channel_buf }; | |
14 | |
15 | |
16 #if 0 | |
17 /* lookup frequency conversion table*/ | |
18 ISDB_T_FREQ_CONV_TABLE * | |
19 searchrecoff(char *channel) | |
20 { | |
21 int lp; | |
22 | |
23 for(lp = 0; isdb_t_conv_table[lp].parm_freq != NULL; lp++) { | |
24 /* return entry number in the table when strings match and | |
25 * lengths are same. */ | |
26 if((memcmp(isdb_t_conv_table[lp].parm_freq, channel, | |
27 strlen(channel)) == 0) && | |
28 (strlen(channel) == strlen(isdb_t_conv_table[lp].parm_freq))) { | |
29 return &isdb_t_conv_table[lp]; | |
30 } | |
31 } | |
32 return NULL; | |
33 } | |
34 #endif | |
35 | |
36 /* lookup frequency conversion table*/ | |
37 ISDB_T_FREQ_CONV_TABLE * | |
38 searchrecoff(char *channel) | |
39 { | |
40 int lp; | |
41 | |
42 if(channel[0] == 'B' && channel[1] == 'S') { | |
43 int node = 0; | |
44 int slot = 0; | |
45 char *bs_ch; | |
46 | |
47 bs_ch = channel + 2; | |
48 while(isdigit(*bs_ch)) { | |
49 node *= 10; | |
50 node += *bs_ch++ - '0'; | |
51 } | |
52 if(*bs_ch == '_' && (node&0x01) && node < ISDB_T_NODE_LIMIT) { | |
53 if(isdigit(*++bs_ch)) { | |
54 slot = *bs_ch - '0'; | |
55 if(*++bs_ch == '\0' && slot < ISDB_T_SLOT_LIMIT) { | |
56 isdb_t_conv_set.set_freq = node / 2; | |
57 isdb_t_conv_set.add_freq = slot; | |
58 sprintf(bs_channel_buf, "BS%d_%d", node, slot); | |
59 return &isdb_t_conv_set; | |
60 } | |
61 } | |
62 } | |
63 return NULL; | |
64 } | |
65 for(lp = 0; isdb_t_conv_table[lp].parm_freq != NULL; lp++) { | |
66 /* return entry number in the table when strings match and | |
67 * lengths are same. */ | |
68 if((memcmp(isdb_t_conv_table[lp].parm_freq, channel, | |
69 strlen(channel)) == 0) && | |
70 (strlen(channel) == strlen(isdb_t_conv_table[lp].parm_freq))) { | |
71 return &isdb_t_conv_table[lp]; | |
72 } | |
73 } | |
74 return NULL; | |
75 } | |
76 | |
77 int | |
78 close_tuner(thread_data *tdata) | |
79 { | |
80 int rv = 0; | |
81 | |
82 if(tdata->tfd == -1) | |
83 return rv; | |
84 | |
85 if(tdata->table->type == CHTYPE_SATELLITE) { | |
86 if(ioctl(tdata->tfd, LNB_DISABLE, 0) < 0) { | |
87 rv = 1; | |
88 } | |
89 } | |
90 close(tdata->tfd); | |
91 tdata->tfd = -1; | |
92 | |
93 return rv; | |
94 } | |
95 | |
96 float | |
97 getsignal_isdb_s(int signal) | |
98 { | |
99 /* apply linear interpolation */ | |
100 static const float afLevelTable[] = { | |
101 24.07f, // 00 00 0 24.07dB | |
102 24.07f, // 10 00 4096 24.07dB | |
103 18.61f, // 20 00 8192 18.61dB | |
104 15.21f, // 30 00 12288 15.21dB | |
105 12.50f, // 40 00 16384 12.50dB | |
106 10.19f, // 50 00 20480 10.19dB | |
107 8.140f, // 60 00 24576 8.140dB | |
108 6.270f, // 70 00 28672 6.270dB | |
109 4.550f, // 80 00 32768 4.550dB | |
110 3.730f, // 88 00 34816 3.730dB | |
111 3.630f, // 88 FF 35071 3.630dB | |
112 2.940f, // 90 00 36864 2.940dB | |
113 1.420f, // A0 00 40960 1.420dB | |
114 0.000f // B0 00 45056 -0.01dB | |
115 }; | |
116 | |
117 unsigned char sigbuf[4]; | |
118 memset(sigbuf, '\0', sizeof(sigbuf)); | |
119 sigbuf[0] = (((signal & 0xFF00) >> 8) & 0XFF); | |
120 sigbuf[1] = (signal & 0xFF); | |
121 | |
122 /* calculate signal level */ | |
123 if(sigbuf[0] <= 0x10U) { | |
124 /* clipped maximum */ | |
125 return 24.07f; | |
126 } | |
127 else if (sigbuf[0] >= 0xB0U) { | |
128 /* clipped minimum */ | |
129 return 0.0f; | |
130 } | |
131 else { | |
132 /* linear interpolation */ | |
133 const float fMixRate = | |
134 (float)(((unsigned short)(sigbuf[0] & 0x0FU) << 8) | | |
135 (unsigned short)sigbuf[0]) / 4096.0f; | |
136 return afLevelTable[sigbuf[0] >> 4] * (1.0f - fMixRate) + | |
137 afLevelTable[(sigbuf[0] >> 4) + 0x01U] * fMixRate; | |
138 } | |
139 } | |
140 | |
141 void | |
142 calc_cn(int fd, int type, boolean use_bell) | |
143 { | |
144 int rc; | |
145 double P; | |
146 double CNR; | |
147 int bell = 0; | |
148 | |
149 if(ioctl(fd, GET_SIGNAL_STRENGTH, &rc) < 0) { | |
150 fprintf(stderr, "Tuner Select Error\n"); | |
151 return ; | |
152 } | |
153 | |
154 if(type == CHTYPE_GROUND) { | |
155 P = log10(5505024/(double)rc) * 10; | |
156 CNR = (0.000024 * P * P * P * P) - (0.0016 * P * P * P) + | |
157 (0.0398 * P * P) + (0.5491 * P)+3.0965; | |
158 } | |
159 else { | |
160 CNR = getsignal_isdb_s(rc); | |
161 } | |
162 | |
163 if(use_bell) { | |
164 if(CNR >= 30.0) | |
165 bell = 3; | |
166 else if(CNR >= 15.0 && CNR < 30.0) | |
167 bell = 2; | |
168 else if(CNR < 15.0) | |
169 bell = 1; | |
170 fprintf(stderr, "\rC/N = %fdB ", CNR); | |
171 do_bell(bell); | |
172 } | |
173 else { | |
174 fprintf(stderr, "\rC/N = %fdB", CNR); | |
175 } | |
176 } | |
177 | |
178 void | |
179 show_channels(void) | |
180 { | |
181 FILE *f; | |
182 char *home; | |
183 char buf[255], filename[255]; | |
184 | |
185 fprintf(stderr, "Available Channels:\n"); | |
186 | |
187 home = getenv("HOME"); | |
188 sprintf(filename, "%s/.recpt1-channels", home); | |
189 f = fopen(filename, "r"); | |
190 if(f) { | |
191 while(fgets(buf, 255, f)) | |
192 fprintf(stderr, "%s", buf); | |
193 fclose(f); | |
194 } | |
195 else | |
196 fprintf(stderr, "13-62: Terrestrial Channels\n"); | |
197 | |
198 fprintf(stderr, "101ch: NHK BS1\n"); | |
199 fprintf(stderr, "103ch: NHK BS Premium\n"); | |
200 fprintf(stderr, "141ch: BS Nittele\n"); | |
201 fprintf(stderr, "151ch: BS Asahi\n"); | |
202 fprintf(stderr, "161ch: BS-TBS\n"); | |
203 fprintf(stderr, "171ch: BS Japan\n"); | |
204 fprintf(stderr, "181ch: BS Fuji\n"); | |
205 fprintf(stderr, "191ch: WOWOW Prime\n"); | |
206 fprintf(stderr, "192ch: WOWOW Live\n"); | |
207 fprintf(stderr, "193ch: WOWOW Cinema\n"); | |
208 fprintf(stderr, "200ch: Star Channel1\n"); | |
209 fprintf(stderr, "201ch: Star Channel2\n"); | |
210 fprintf(stderr, "202ch: Star Channel3\n"); | |
211 fprintf(stderr, "211ch: BS11 Digital\n"); | |
212 fprintf(stderr, "222ch: TwellV\n"); | |
213 fprintf(stderr, "231ch: Housou Daigaku 1\n"); | |
214 fprintf(stderr, "232ch: Housou Daigaku 2\n"); | |
215 fprintf(stderr, "233ch: Housou Daigaku 3\n"); | |
216 fprintf(stderr, "234ch: Green Channel\n"); | |
217 fprintf(stderr, "236ch: BS Animax\n"); | |
218 fprintf(stderr, "238ch: FOX bs238\n"); | |
219 fprintf(stderr, "241ch: BS SkyPer!\n"); | |
220 fprintf(stderr, "242ch: J SPORTS 1\n"); | |
221 fprintf(stderr, "243ch: J SPORTS 2\n"); | |
222 fprintf(stderr, "244ch: J SPORTS 3\n"); | |
223 fprintf(stderr, "245ch: J SPORTS 4\n"); | |
224 fprintf(stderr, "251ch: BS Tsuri Vision\n"); | |
225 fprintf(stderr, "252ch: IMAGICA BS\n"); | |
226 fprintf(stderr, "255ch: Nihon Eiga Senmon Channel\n"); | |
227 fprintf(stderr, "256ch: Disney Channel\n"); | |
228 fprintf(stderr, "258ch: Dlife\n"); | |
229 fprintf(stderr, "C13-C63: CATV Channels\n"); | |
230 fprintf(stderr, "CS2-CS24: CS Channels\n"); | |
231 } | |
232 | |
233 | |
234 #if 0 | |
235 int | |
236 parse_time(char *rectimestr, thread_data *tdata) | |
237 { | |
238 /* indefinite */ | |
239 if(!strcmp("-", rectimestr)) { | |
240 tdata->indefinite = TRUE; | |
241 tdata->recsec = -1; | |
242 return 0; | |
243 } | |
244 /* colon */ | |
245 else if(strchr(rectimestr, ':')) { | |
246 int n1, n2, n3; | |
247 if(sscanf(rectimestr, "%d:%d:%d", &n1, &n2, &n3) == 3) | |
248 tdata->recsec = n1 * 3600 + n2 * 60 + n3; | |
249 else if(sscanf(rectimestr, "%d:%d", &n1, &n2) == 2) | |
250 tdata->recsec = n1 * 3600 + n2 * 60; | |
251 else | |
252 return 1; | |
253 return 0; | |
254 } | |
255 /* HMS */ | |
256 else { | |
257 char *tmpstr; | |
258 char *p1, *p2; | |
259 | |
260 tmpstr = strdup(rectimestr); | |
261 p1 = tmpstr; | |
262 while(*p1 && !isdigit(*p1)) | |
263 p1++; | |
264 | |
265 /* hour */ | |
266 if((p2 = strchr(p1, 'H')) || (p2 = strchr(p1, 'h'))) { | |
267 *p2 = '\0'; | |
268 tdata->recsec += atoi(p1) * 3600; | |
269 p1 = p2 + 1; | |
270 while(*p1 && !isdigit(*p1)) | |
271 p1++; | |
272 } | |
273 | |
274 /* minute */ | |
275 if((p2 = strchr(p1, 'M')) || (p2 = strchr(p1, 'm'))) { | |
276 *p2 = '\0'; | |
277 tdata->recsec += atoi(p1) * 60; | |
278 p1 = p2 + 1; | |
279 while(*p1 && !isdigit(*p1)) | |
280 p1++; | |
281 } | |
282 | |
283 /* second */ | |
284 tdata->recsec += atoi(p1); | |
285 | |
286 free(tmpstr); | |
287 return 0; | |
288 } /* else */ | |
289 | |
290 return 1; /* unsuccessful */ | |
291 } | |
292 #endif | |
293 | |
294 int | |
295 parse_time(char *rectimestr, int *recsec) | |
296 { | |
297 /* indefinite */ | |
298 if(!strcmp("-", rectimestr)) { | |
299 *recsec = -1; | |
300 } | |
301 /* colon */ | |
302 else if(strchr(rectimestr, ':')) { | |
303 int n1, n2, n3; | |
304 if(sscanf(rectimestr, "%d:%d:%d", &n1, &n2, &n3) == 3) | |
305 *recsec = n1 * 3600 + n2 * 60 + n3; | |
306 else if(sscanf(rectimestr, "%d:%d", &n1, &n2) == 2) | |
307 *recsec = n1 * 3600 + n2 * 60; | |
308 else | |
309 return 1; /* unsuccessful */ | |
310 | |
311 return 0; | |
312 } | |
313 /* HMS */ | |
314 else { | |
315 char *tmpstr; | |
316 char *p1, *p2; | |
317 | |
318 tmpstr = strdup(rectimestr); | |
319 p1 = tmpstr; | |
320 while(*p1 && !isdigit(*p1)) | |
321 p1++; | |
322 | |
323 /* hour */ | |
324 if((p2 = strchr(p1, 'H')) || (p2 = strchr(p1, 'h'))) { | |
325 *p2 = '\0'; | |
326 *recsec += atoi(p1) * 3600; | |
327 p1 = p2 + 1; | |
328 while(*p1 && !isdigit(*p1)) | |
329 p1++; | |
330 } | |
331 | |
332 /* minute */ | |
333 if((p2 = strchr(p1, 'M')) || (p2 = strchr(p1, 'm'))) { | |
334 *p2 = '\0'; | |
335 *recsec += atoi(p1) * 60; | |
336 p1 = p2 + 1; | |
337 while(*p1 && !isdigit(*p1)) | |
338 p1++; | |
339 } | |
340 | |
341 /* second */ | |
342 *recsec += atoi(p1); | |
343 | |
344 free(tmpstr); | |
345 | |
346 return 0; | |
347 } /* else */ | |
348 | |
349 return 1; /* unsuccessful */ | |
350 } | |
351 | |
352 void | |
353 do_bell(int bell) | |
354 { | |
355 int i; | |
356 for(i=0; i < bell; i++) { | |
357 fprintf(stderr, "\a"); | |
358 usleep(400000); | |
359 } | |
360 } | |
361 | |
362 /* from checksignal.c */ | |
363 int | |
364 tune(char *channel, thread_data *tdata, char *device) | |
365 { | |
366 char **tuner; | |
367 int num_devs; | |
368 int lp; | |
369 FREQUENCY freq; | |
370 | |
371 /* get channel */ | |
372 tdata->table = searchrecoff(channel); | |
373 if(tdata->table == NULL) { | |
374 fprintf(stderr, "Invalid Channel: %s\n", channel); | |
375 return 1; | |
376 } | |
377 | |
378 freq.frequencyno = tdata->table->set_freq; | |
379 freq.slot = tdata->table->add_freq; | |
380 | |
381 /* open tuner */ | |
382 /* case 1: specified tuner device */ | |
383 if(device) { | |
384 tdata->tfd = open(device, O_RDONLY); | |
385 if(tdata->tfd < 0) { | |
386 fprintf(stderr, "Cannot open tuner device: %s\n", device); | |
387 return 1; | |
388 } | |
389 | |
390 /* power on LNB */ | |
391 if(tdata->table->type == CHTYPE_SATELLITE) { | |
392 if(ioctl(tdata->tfd, LNB_ENABLE, tdata->lnb) < 0) { | |
393 fprintf(stderr, "Power on LNB failed: %s\n", device); | |
394 } | |
395 } | |
396 | |
397 /* tune to specified channel */ | |
398 while(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) { | |
399 if(tdata->tune_persistent) { | |
400 if(f_exit) { | |
401 close_tuner(tdata); | |
402 return 1; | |
403 } | |
404 fprintf(stderr, "No signal. Still trying: %s\n", device); | |
405 } | |
406 else { | |
407 close(tdata->tfd); | |
408 fprintf(stderr, "Cannot tune to the specified channel: %s\n", device); | |
409 return 1; | |
410 } | |
411 } | |
412 | |
413 fprintf(stderr, "device = %s\n", device); | |
414 } | |
415 else { | |
416 /* case 2: loop around available devices */ | |
417 if(tdata->table->type == CHTYPE_SATELLITE) { | |
418 tuner = bsdev; | |
419 num_devs = NUM_BSDEV; | |
420 } | |
421 else { | |
422 tuner = isdb_t_dev; | |
423 num_devs = NUM_ISDB_T_DEV; | |
424 } | |
425 | |
426 for(lp = 0; lp < num_devs; lp++) { | |
427 int count = 0; | |
428 | |
429 tdata->tfd = open(tuner[lp], O_RDONLY); | |
430 if(tdata->tfd >= 0) { | |
431 /* power on LNB */ | |
432 if(tdata->table->type == CHTYPE_SATELLITE) { | |
433 if(ioctl(tdata->tfd, LNB_ENABLE, tdata->lnb) < 0) { | |
434 fprintf(stderr, "Warning: Power on LNB failed: %s\n", tuner[lp]); | |
435 } | |
436 } | |
437 | |
438 /* tune to specified channel */ | |
439 if(tdata->tune_persistent) { | |
440 while(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0 && | |
441 count < MAX_RETRY) { | |
442 if(f_exit) { | |
443 close_tuner(tdata); | |
444 return 1; | |
445 } | |
446 fprintf(stderr, "No signal. Still trying: %s\n", tuner[lp]); | |
447 count++; | |
448 } | |
449 | |
450 if(count >= MAX_RETRY) { | |
451 close_tuner(tdata); | |
452 count = 0; | |
453 continue; | |
454 } | |
455 } /* tune_persistent */ | |
456 else { | |
457 if(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) { | |
458 close(tdata->tfd); | |
459 tdata->tfd = -1; | |
460 continue; | |
461 } | |
462 } | |
463 | |
464 if(tdata->tune_persistent) | |
465 fprintf(stderr, "device = %s\n", tuner[lp]); | |
466 break; /* found suitable tuner */ | |
467 } | |
468 } | |
469 | |
470 /* all tuners cannot be used */ | |
471 if(tdata->tfd < 0) { | |
472 fprintf(stderr, "Cannot tune to the specified channel\n"); | |
473 return 1; | |
474 } | |
475 } | |
476 | |
477 if(!tdata->tune_persistent) { | |
478 /* show signal strength */ | |
479 calc_cn(tdata->tfd, tdata->table->type, FALSE); | |
480 } | |
481 | |
482 return 0; /* success */ | |
483 } | |
484 | |
485 | |
486 #if 0 | |
487 /* from recpt1.c */ | |
488 int | |
489 tune(char *channel, thread_data *tdata, char *device) | |
490 { | |
491 char **tuner; | |
492 int num_devs; | |
493 int lp; | |
494 FREQUENCY freq; | |
495 | |
496 /* get channel */ | |
497 tdata->table = searchrecoff(channel); | |
498 if(tdata->table == NULL) { | |
499 fprintf(stderr, "Invalid Channel: %s\n", channel); | |
500 return 1; | |
501 } | |
502 | |
503 freq.frequencyno = tdata->table->set_freq; | |
504 freq.slot = tdata->table->add_freq; | |
505 | |
506 /* open tuner */ | |
507 /* case 1: specified tuner device */ | |
508 if(device) { | |
509 tdata->tfd = open(device, O_RDONLY); | |
510 if(tdata->tfd < 0) { | |
511 fprintf(stderr, "Cannot open tuner device: %s\n", device); | |
512 return 1; | |
513 } | |
514 | |
515 /* power on LNB */ | |
516 if(tdata->table->type == CHTYPE_SATELLITE) { | |
517 if(ioctl(tdata->tfd, LNB_ENABLE, tdata->lnb) < 0) { | |
518 fprintf(stderr, "Power on LNB failed: %s\n", device); | |
519 } | |
520 } | |
521 | |
522 /* tune to specified channel */ | |
523 if(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) { | |
524 close(tdata->tfd); | |
525 fprintf(stderr, "Cannot tune to the specified channel: %s\n", device); | |
526 return 1; | |
527 } | |
528 } | |
529 else { | |
530 /* case 2: loop around available devices */ | |
531 if(tdata->table->type == CHTYPE_SATELLITE) { | |
532 tuner = bsdev; | |
533 num_devs = NUM_BSDEV; | |
534 } | |
535 else { | |
536 tuner = isdb_t_dev; | |
537 num_devs = NUM_ISDB_T_DEV; | |
538 } | |
539 | |
540 for(lp = 0; lp < num_devs; lp++) { | |
541 tdata->tfd = open(tuner[lp], O_RDONLY); | |
542 if(tdata->tfd >= 0) { | |
543 /* power on LNB */ | |
544 if(tdata->table->type == CHTYPE_SATELLITE) { | |
545 if(ioctl(tdata->tfd, LNB_ENABLE, tdata->lnb) < 0) { | |
546 fprintf(stderr, "Warning: Power on LNB failed: %s\n", tuner[lp]); | |
547 } | |
548 } | |
549 | |
550 /* tune to specified channel */ | |
551 if(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) { | |
552 close(tdata->tfd); | |
553 tdata->tfd = -1; | |
554 continue; | |
555 } | |
556 | |
557 break; /* found suitable tuner */ | |
558 } | |
559 } | |
560 | |
561 /* all tuners cannot be used */ | |
562 if(tdata->tfd < 0) { | |
563 fprintf(stderr, "Cannot tune to the specified channel\n"); | |
564 return 1; | |
565 } | |
566 } | |
567 | |
568 /* show signal strength */ | |
569 calc_cn(tdata->tfd, tdata->table->type, FALSE); | |
570 | |
571 return 0; /* success */ | |
572 } | |
573 #endif |