changeset 20985:20110e4437c6

Add *BSD BT848 radio support
author voroshil
date Sat, 18 Nov 2006 06:53:33 +0000
parents 41773d188756
children 2422495f5e78
files DOCS/man/en/mplayer.1 cfg-common.h configure help/help_mp-en.h stream/stream_radio.c stream/stream_radio.h
diffstat 6 files changed, 198 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/DOCS/man/en/mplayer.1	Sat Nov 18 02:40:19 2006 +0000
+++ b/DOCS/man/en/mplayer.1	Sat Nov 18 06:53:33 2006 +0000
@@ -1616,12 +1616,16 @@
 Available options are:
 .RSs
 .IPs device=<value>
-Radio device to use (default: /dev/radio0).
+Radio device to use (default: /dev/radio0 for Linux and /dev/tuner0 for *BSD).
 .IPs driver=<value>
 Radio driver to use (default: v4l2 if available, otherwise v4l).
 Currently, v4l and v4l2 drivers are supported.
 .IPs volume=<0..100>
 sound volume for radio device (default 100)
+.IPs freq_min=<value> (*BSD BT848 only)
+minimum allowed frequency (default: 87.50)
+.IPs freq_max=<value> (*BSD BT848 only)
+maximum allowed frequency (default: 108.00)
 .IPs channels=<frequency>\-<name>,<frequency>\-<name>,...
 Set channel list.
 Use _ for spaces in names (or play with quoting ;-).
--- a/cfg-common.h	Sat Nov 18 02:40:19 2006 +0000
+++ b/cfg-common.h	Sat Nov 18 06:53:33 2006 +0000
@@ -394,6 +394,10 @@
 m_option_t radioopts_conf[]={
     {"device", &radio_param_device, CONF_TYPE_STRING, 0, 0 ,0, NULL},
     {"driver", &radio_param_driver, CONF_TYPE_STRING, 0, 0 ,0, NULL},
+#ifdef RADIO_BSDBT848_HDR
+    {"freq_min", &radio_param_freq_min, CONF_TYPE_FLOAT, 0, 0 ,0, NULL},
+    {"freq_max", &radio_param_freq_max, CONF_TYPE_FLOAT, 0, 0 ,0, NULL},
+#endif
     {"channels", &radio_param_channels, CONF_TYPE_STRING_LIST, 0, 0 ,0, NULL},
     {"volume", &radio_param_volume, CONF_TYPE_INT, CONF_RANGE, 0 ,100, NULL},
     {"adevice", &radio_param_adevice, CONF_TYPE_STRING, 0, 0 ,0, NULL},
--- a/configure	Sat Nov 18 02:40:19 2006 +0000
+++ b/configure	Sat Nov 18 06:53:33 2006 +0000
@@ -228,6 +228,7 @@
   --enable-radio         enable radio interface [disable]
   --enable-radio-capture enable radio capture (through PCI/line-in) [disable]
   --disable-radio-v4l2   disable Video4Linux2 radio interface [autodetect]
+  --disable-radio-bsdbt848   disable BSD BT848 radio interface [autodetect]
   --disable-tv           disable TV interface (TV/DVB grabbers) [enable]
   --disable-tv-v4l1      disable Video4Linux TV interface [autodetect]
   --disable-tv-v4l2      disable Video4Linux2 TV interface [autodetect]
@@ -1647,6 +1648,7 @@
 _radio_capture=no
 _radio_v4l=auto
 _radio_v4l2=auto
+_radio_bsdbt848=auto
 _tv=yes
 _tv_v4l1=auto
 _tv_v4l2=auto
@@ -1904,6 +1906,8 @@
   --disable-radio-v4l)	_radio_v4l=no	;;
   --enable-radio-v4l2)	_radio_v4l2=yes	;;
   --disable-radio-v4l2)	_radio_v4l2=no	;;
+  --enable-radio-bsdbt848)	_radio_bsdbt848=yes	;;
+  --disable-radio-bsdbt848)	_radio_bsdbt848=no	;;
   --enable-pvr)  	_pvr=yes	;;
   --disable-pvr)	_pvr=no 	;;
   --enable-fastmemcpy)	_fastmemcpy=yes	;;
@@ -6723,8 +6727,31 @@
 fi
 echores "$_radio_v4l"
 
-if test "$_radio_v4l" = no && test "$_radio_v4l2" = no && test "$_radio" = yes ; then
-    die "Radio driver requires V4L or V4L2!"
+if bsd && test "$_radio" = yes && test "$_radio_bsdbt848" = auto ; then
+echocheck "*BSD BrookTree 848 Radio interface header"
+  for file in "dev/ic/bt8xx.h" \
+              "machine/ioctl_bt848.h" \
+              "dev/bktr/ioctl_bt848.h" \
+              "dev/video/bktr/ioctl_bt848.h" ; do
+    cat > $TMPC <<EOF
+#include <sys/types.h>
+#include <$file>
+int main(void) { return 0; }
+EOF
+    cc_check && _radio_bsdbt848_hdr=$file
+  done
+echores "$_radio_bsdbt848_hdr"
+fi #if bsd && radio && radio_bsdbt848
+
+if test -n "$_radio_bsdbt848_hdr"  ; then
+  _def_radio_bsdbt848="#define RADIO_BSDBT848_HDR <$_radio_bsdbt848_hdr>"
+else
+  _def_radio_bsdbt848='#undef RADIO_BSDBT848_HDR '
+fi
+
+if test "$_radio_v4l" = no && test "$_radio_v4l2" = no && \
+   test -z "$_radio_bsdbt848_hdr" && test "$_radio" = yes ; then
+    die "Radio driver requires BSD BT848,  V4L or V4L2!"
 fi
 
 echocheck "Video 4 Linux 2 MPEG PVR interface"
@@ -7954,6 +7981,9 @@
 /* Enable Video 4 Linux 2 Radio interface support */
 $_def_radio_v4l2
 
+/* Enable *BSD BrookTree Radio interface support */
+$_def_radio_bsdbt848
+
 /* Enable Video 4 Linux 2 MPEG PVR support */
 $_def_pvr
 
--- a/help/help_mp-en.h	Sat Nov 18 02:40:19 2006 +0000
+++ b/help/help_mp-en.h	Sat Nov 18 06:53:33 2006 +0000
@@ -1960,4 +1960,5 @@
 #define MSGTR_RADIO_DriverUnknownStr "[radio] Unknown driver name: %s\n"
 #define MSGTR_RADIO_DriverV4L2 "[radio] Using V4Lv2 radio interface.\n"
 #define MSGTR_RADIO_DriverV4L "[radio] Using V4Lv1 radio interface.\n"
+#define MSGTR_RADIO_DriverBSDBT848 "[radio] Using *BSD BT848 radio interface.\n"
 
--- a/stream/stream_radio.c	Sat Nov 18 02:40:19 2006 +0000
+++ b/stream/stream_radio.c	Sat Nov 18 06:53:33 2006 +0000
@@ -33,6 +33,13 @@
 #include <sys/ioctl.h>
 #include <errno.h>
 #include <unistd.h>
+
+#ifdef RADIO_BSDBT848_HDR
+#include <sys/param.h>
+#include RADIO_BSDBT848_HDR
+
+#else // RADIO_BSDBT848_HDR
+
 #include <linux/types.h>
 
 #ifdef HAVE_RADIO_V4L2
@@ -44,6 +51,7 @@
 #warning  "V4L is deprecated and will be removed in future"
 #endif
 
+#endif // !RADIO_BSDBT848_HDR
 
 
 #include "stream.h"
@@ -72,6 +80,7 @@
 #define RADIO_DRIVER_UNKNOWN    0
 #define RADIO_DRIVER_V4L        1
 #define RADIO_DRIVER_V4L2       2
+#define RADIO_DRIVER_BSDBT848   3
 
 typedef struct radio_channels_s {
     int index;     ///< channel index in channels list
@@ -81,8 +90,17 @@
     struct radio_channels_s * prev;
 } radio_channels_t;
 
+#ifdef RADIO_BSDBT848_HDR
+/** (device,string, "/dev/tuner0") name of radio device file */
+char*   radio_param_device="/dev/tuner0";
+/** radio_param_freq_min (freq_min,float,87.5) minimal allowed frequency */
+float radio_param_freq_min=87.50;
+/** radio_param_freq_min (freq_min,float,108.0) maximal allowed frequency */
+float radio_param_freq_max=108.00;
+#else
 /** (device,string, "/dev/radio0") name of radio device file */
 char*   radio_param_device="/dev/radio0";
+#endif
 /** (driver,string, "v4l2") radio driver (v4l,v4l2) */
 char*   radio_param_driver="default";
 /** radio_param_channels (channels,string,NULL) channels list (see man page) */
@@ -507,6 +525,106 @@
     return STREAM_ERROR;
 }
 #endif //HAVE_RADIO_V4L
+#ifdef RADIO_BSDBT848_HDR
+/*****************************************************************
+ * \brief get fraction value for using in set_frequency and get_frequency
+ * \return STREAM_OK if success, STREAM_ERROR otherwise
+ *
+ * For *BSD BT848 frac=100
+ *
+ * Here is a coment from FreeBSD 5.2-RELEASE source code:
+ *
+ * * Tuner Notes:
+ * * Programming the tuner properly is quite complicated.
+ * * Here are some notes, based on a FM1246 data sheet for a PAL-I tuner.
+ * * The tuner (front end) covers 45.75 MHz - 855.25 MHz and an FM band of
+ * * 87.5 MHz to 108.0 MHz.
+ *
+ * Thus, frequency range is limited to 87.5-108.0, but you can change
+ * it, using freq_min and freq_max options
+*/
+static int init_frac_bsdbt848(radio_priv_t* priv){
+    priv->frac=100;
+    priv->rangelow=radio_param_freq_min;
+    priv->rangehigh=radio_param_freq_max;
+    return STREAM_OK;
+}
+
+/*****************************************************************
+ * \brief tune card to given frequency
+ * \param frequency frequency in MHz
+ * \return STREAM_OK if success, STREAM_ERROR otherwise
+ */
+static int set_frequency_bsdbt848(radio_priv_t* priv,float frequency){
+    unsigned int freq;
+    freq=frequency*priv->frac;
+    if(ioctl(priv->radio_fd,RADIO_SETFREQ,&freq)<0){
+        mp_msg(MSGT_RADIO,MSGL_ERR,MSGTR_RADIO_SetFreqFailed,freq, frequency, strerror(errno));
+        return  STREAM_ERROR;
+    }
+    return STREAM_OK;
+}
+
+/*****************************************************************
+ * \brief get current tuned frequency from card
+ * \param frequency where to store frequency in MHz
+ * \return STREAM_OK if success, STREAM_ERROR otherwise
+ */
+static int get_frequency_bsdbt848(radio_priv_t* priv,float* frequency){
+    unsigned int freq;
+    if (ioctl(priv->radio_fd, RADIO_GETFREQ, &freq) < 0) {
+        mp_msg(MSGT_RADIO,MSGL_ERR,MSGTR_RADIO_GetFreqFailed,strerror(errno));
+        return  STREAM_ERROR;
+    }
+    *frequency=((float)freq)/priv->frac;
+    return STREAM_OK;
+}
+
+/*****************************************************************
+ * \brief set volume on radio card
+ * \param volume volume level (0..100)
+ * \return STREAM_OK if success, STREAM_ERROR otherwise
+ *
+ * *BSD BT848 does not have volume changing abilities, so
+ * we will just mute sound if volume=0 and unmute it otherwise.
+ */
+static void set_volume_bsdbt848(radio_priv_t* priv,int volume){
+    int audio_flags;
+
+    /*arg must be between 0 and 100*/
+    if (volume > 100) volume = 100;
+    if (volume < 0) volume = 0;
+
+    audio_flags = (volume==0?AUDIO_MUTE:AUDIO_UNMUTE);
+    if (ioctl(priv->radio_fd, BT848_SAUDIO, &audio_flags)<0){
+            mp_msg(MSGT_RADIO,MSGL_WARN,MSGTR_RADIO_SetMuteFailed,strerror(errno));
+    }
+}
+
+/*****************************************************************
+ * \brief get current volume from radio card
+ * \param volume where to store volume level (0..100)
+ * \return previous STREAM_OK if success, STREAM_ERROR otherwise
+ *
+ * *BSD BT848 does not have volume changing abilities, so
+ * we will return 0 if sound is muted and 100 otherwise.
+ */
+static int get_volume_bsdbt848(radio_priv_t* priv,int* volume){
+    int audio_flags;
+
+    if (ioctl(priv->radio_fd, BT848_GAUDIO, &audio_flags)<0){
+        mp_msg(MSGT_RADIO,MSGL_ERR,MSGTR_RADIO_GetVolumeFailed,strerror(errno));
+        return STREAM_ERROR;
+    }
+
+    if (audio_flags & AUDIO_MUTE)
+        *volume=0;
+    else
+        *volume=100;
+
+    return STREAM_OK;
+}
+#endif //RADIO_BSDBT848_HDR
 
 static inline int init_frac(radio_priv_t* priv){ 
     switch(priv->driver){
@@ -518,6 +636,10 @@
         case RADIO_DRIVER_V4L2:
             return init_frac_v4l2(priv);
 #endif
+#ifdef RADIO_BSDBT848_HDR
+        case RADIO_DRIVER_BSDBT848:
+            return init_frac_bsdbt848(priv);
+#endif
     }
     mp_msg(MSGT_RADIO,MSGL_ERR,MSGTR_RADIO_DriverUnknownId,priv->driver);
     return STREAM_ERROR;
@@ -540,6 +662,12 @@
                 return STREAM_ERROR;
             break;     
 #endif
+#ifdef RADIO_BSDBT848_HDR
+        case RADIO_DRIVER_BSDBT848:
+            if(set_frequency_bsdbt848(priv,frequency)!=STREAM_OK)
+                return STREAM_ERROR;
+            break;
+#endif
         default:
             mp_msg(MSGT_RADIO,MSGL_ERR,MSGTR_RADIO_DriverUnknownId,priv->driver);
             return STREAM_ERROR;
@@ -562,6 +690,10 @@
         case RADIO_DRIVER_V4L2:
             return get_frequency_v4l2(priv,frequency);
 #endif
+#ifdef RADIO_BSDBT848_HDR
+        case RADIO_DRIVER_BSDBT848:
+            return get_frequency_bsdbt848(priv,frequency);
+#endif
     }
     mp_msg(MSGT_RADIO,MSGL_ERR,MSGTR_RADIO_DriverUnknownId,priv->driver);
     return STREAM_ERROR;
@@ -578,6 +710,11 @@
             set_volume_v4l2(priv,volume);
             return;
 #endif
+#ifdef RADIO_BSDBT848_HDR
+        case RADIO_DRIVER_BSDBT848:
+            set_volume_bsdbt848(priv,volume);
+            return;
+#endif
     }
     mp_msg(MSGT_RADIO,MSGL_ERR,MSGTR_RADIO_DriverUnknownId,priv->driver);
 }
@@ -591,6 +728,10 @@
         case RADIO_DRIVER_V4L2:
             return get_volume_v4l2(priv,volume);
 #endif
+#ifdef RADIO_BSDBT848_HDR
+        case RADIO_DRIVER_BSDBT848:
+            return get_volume_bsdbt848(priv,volume);
+#endif
     }
     mp_msg(MSGT_RADIO,MSGL_ERR,MSGTR_RADIO_DriverUnknownId,priv->driver);
     return STREAM_ERROR;
@@ -996,8 +1137,10 @@
 
 
     if (strncmp(radio_param_driver,"default",7)==0)
-#ifdef HAVE_RADIO_V4L2
+#if defined(HAVE_RADIO_V4L2)
         priv->driver=RADIO_DRIVER_V4L2;
+#elif defined(RADIO_BSDBT848_HDR)
+        priv->driver=RADIO_DRIVER_BSDBT848;
 #else
         priv->driver=RADIO_DRIVER_V4L;
 #endif
@@ -1012,6 +1155,11 @@
         priv->driver=RADIO_DRIVER_V4L;
     else
 #endif
+#ifdef RADIO_BSDBT848_HDR
+    if (strncmp(radio_param_driver,"bsdbt848",8)==0)
+        priv->driver=RADIO_DRIVER_BSDBT848;
+    else
+#endif
     priv->driver=RADIO_DRIVER_UNKNOWN;
 
 
@@ -1022,6 +1170,9 @@
         case RADIO_DRIVER_V4L2:
             mp_msg(MSGT_RADIO, MSGL_INFO, MSGTR_RADIO_DriverV4L2);
             break;
+        case RADIO_DRIVER_BSDBT848:
+            mp_msg(MSGT_RADIO, MSGL_INFO, MSGTR_RADIO_DriverBSDBT848);
+            break;
         default:
             mp_msg(MSGT_RADIO, MSGL_INFO, MSGTR_RADIO_DriverUnknownStr,radio_param_driver);
             close_s(stream);
--- a/stream/stream_radio.h	Sat Nov 18 02:40:19 2006 +0000
+++ b/stream/stream_radio.h	Sat Nov 18 06:53:33 2006 +0000
@@ -7,6 +7,10 @@
 
 extern char *radio_param_device;
 extern char *radio_param_driver;
+#ifdef RADIO_BSDBT848_HDR
+extern float radio_param_freq_min;
+extern float radio_param_freq_max;
+#endif
 extern char **radio_param_channels;
 extern int radio_param_volume;
 extern char* radio_param_adevice;