diff recpt1/recpt1.c @ 11:4615eaf04415

support signal strength calculation.
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Mon, 23 Feb 2009 14:53:12 +0900
parents 6da603afd363
children 003fe2470af8
line wrap: on
line diff
--- a/recpt1/recpt1.c	Mon Feb 23 14:35:26 2009 +0900
+++ b/recpt1/recpt1.c	Mon Feb 23 14:53:12 2009 +0900
@@ -6,6 +6,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <pthread.h>
+#include <math.h>
 #include <unistd.h>
 #include <getopt.h>
 
@@ -231,6 +232,73 @@
     fprintf(stderr, "Usage: %s [--b25 [--round N] [--strip] [--EMM]] [--udp hostname [--port port]] channel recsec destfile\n", cmd);
 }
 
+float
+getsignal_isdb_s(int signal)
+{
+    // 線形補完で近似する
+    static const float afLevelTable[] = {
+        24.07f,    // 00    00    0        24.07dB
+        24.07f,    // 10    00    4096     24.07dB
+        18.61f,    // 20    00    8192     18.61dB
+        15.21f,    // 30    00    12288    15.21dB
+        12.50f,    // 40    00    16384    12.50dB
+        10.19f,    // 50    00    20480    10.19dB
+        8.140f,    // 60    00    24576    8.140dB
+        6.270f,    // 70    00    28672    6.270dB
+        4.550f,    // 80    00    32768    4.550dB
+        3.730f,    // 88    00    34816    3.730dB
+        3.630f,    // 88    FF    35071    3.630dB
+        2.940f,    // 90    00    36864    2.940dB
+        1.420f,    // A0    00    40960    1.420dB
+        0.000f     // B0    00    45056    -0.01dB
+    };
+
+    unsigned char sigbuf[4];
+    memset(sigbuf, '\0', sizeof(sigbuf));
+    sigbuf[0] =  (((signal & 0xFF00) >> 8) & 0XFF);
+    sigbuf[1] =  (signal & 0xFF);
+
+    // 信号レベル計算
+    if(sigbuf[0] <= 0x10U){
+        // 最大クリップ
+        return 24.07f;
+    } else if (sigbuf[0] >= 0xB0U) {
+        // 最小クリップ
+        return 0.0f;
+    } else {
+        // 線形補完
+        const float fMixRate =
+            (float)(((unsigned short)(sigbuf[0] & 0x0FU) << 8) |
+                    (unsigned short)sigbuf[0]) / 4096.0f;
+        return afLevelTable[sigbuf[0] >> 4] * (1.0f - fMixRate) +
+            afLevelTable[(sigbuf[0] >> 4) + 0x01U] * fMixRate;
+    }
+}
+
+void
+calc_cn(int fd, int type)
+{
+
+    int     rc ;
+    double  P ;
+    double  CNR;
+
+    if(ioctl(fd, GET_SIGNAL_STRENGTH, &rc) < 0) {
+        printf("Tuner Select Error\n");
+        return ;
+    }
+
+    if(type == CHTYPE_GROUND) {
+        P = log10(5505024/(double)rc) * 10;
+        CNR = (0.000024 * P * P * P * P) - (0.0016 * P * P * P) +
+                    (0.0398 * P * P) + (0.5491 * P)+3.0965;
+        printf("Signal=%fdB\n", CNR);
+    } else {
+        CNR = getsignal_isdb_s(rc);
+        printf("Signal=%fdB\n", CNR);
+    }
+}
+
 int
 main(int argc, char **argv)
 {
@@ -397,10 +465,18 @@
         return 1;
     }
 
+    if(ptr->type == CHTYPE_SATELLITE){
+        if(ioctl(tfd, LNB_ENABLE, 0) < 0){
+            return 0 ;
+        }
+    }
+
     if(ioctl(tfd, SET_CHANNEL, &freq) < 0) {
         fprintf(stderr, "Tuner Select Error\n");
+		calc_cn(tfd, ptr->type);
         return 1;
     }
+    calc_cn(tfd, ptr->type);
 
     /* make reader thread */
     tdata.queue = p_queue;
@@ -451,6 +527,11 @@
         }
     }
     /* close tuner */
+    if(ptr->type == CHTYPE_SATELLITE){
+        if(ioctl(tfd, LNB_DISABLE, 0) < 0){
+            return 0 ;
+        }
+    }
     close(tfd);
 
     /* wait reader thread */