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
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