[MPlayer-dev-eng] BSD BT848 Radio interface (patch)

Vladimir Kushnir vkushnir at i.kiev.ua
Sat Nov 4 01:55:59 CET 2006


Hi all,

Thanks for a very good work.
Now to the business :-) I've added BSD (well, actually FreeBSD and 
probably DragonFly) bktr (bsdbt848) interface to radio 
FM stream handling. What works: setting channels/frequencies, setting 
volume through line-in channel of OSS mixer and restoration of old 
value on exit. What doesn't work: setting arate and achannels (I 
think I could do that but - honestly - don't really see any reason to), 
setting of the different mixer device.

Thanks again.
Regards,
Vladimir
-------------- next part --------------
--- configure.orig	Sat Nov  4 02:22:26 2006
+++ configure	Sat Nov  4 02:47:58 2006
@@ -229,6 +229,7 @@
   --enable-radio         enable Radio Interface [disable]
   --enable-radio-capture enable Capture for Radio Interface (through pci/line-in) [disable]
   --disable-radio-v4l2   disable Video4Linux2 Radio Interface support [autodetect]
+  --disable-radio-bsdbt848  disable BSD BT848 Radio Interface support [autodetect]
   --disable-tv           disable TV Interface (tv/dvb grabbers) [enable]
   --disable-tv-v4l1      disable Video4Linux TV Interface support [autodetect]
   --disable-tv-v4l2      disable Video4Linux2 TV Interface support [autodetect]
@@ -1665,6 +1666,7 @@
 _radio_capture=no
 _radio_v4l=auto
 _radio_v4l2=auto
+_radio_bsdbt848=auto
 _tv=yes
 _tv_v4l1=auto
 _tv_v4l2=auto
@@ -1921,6 +1923,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	;;
@@ -6777,8 +6781,39 @@
 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; then
+echocheck "*BSD BrookTree 848 Radio interface"
+if test "$_radio_bsdbt848" = auto ; then
+  _radio_bsdbt848=no
+  if test "$_radio" = yes ; then
+    cat > $TMPC <<EOF
+#include <sys/types.h>
+#include <sys/param.h>
+#if defined(__DragonFly__)
+#include <dev/video/meteor/ioctl_meteor.h>
+#include <dev/video/bktr/ioctl_bt848.h>
+#elif __FreeBSD_version >= 502100
+#include <dev/bktr/ioctl_meteor.h>
+#include <dev/bktr/ioctl_bt848.h>
+#else
+#include <machine/ioctl_meteor.h>
+#include <machine/ioctl_bt848.h>
+#endif
+int main(void) { return 0; }
+EOF
+    cc_check && _radio_bsdbt848=yes
+  fi
+fi
+if test "$_radio_bsdbt848" = yes ; then
+  _def_radio_bsdbt848='#define HAVE_RADIO_BSDBT848 1'
+else
+  _def_radio_bsdbt848='#undef HAVE_RADIO_BSDBT848'
+fi
+echores "$_radio_bsdbt848"
+fi #bsd
+
+if test "$_radio_v4l" = no && test "$_radio_v4l2" = no && test "$_radio_bsdbt848" = no && test "$_radio" = yes ; then
+    die "Radio driver requires BSD BT848,  V4L or V4L2!"
 fi
 
 echocheck "Video 4 Linux 2 MPEG PVR interface"
@@ -8006,6 +8041,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
--- help/help_mp-en.h.orig	Sat Nov  4 02:22:25 2006
+++ help/help_mp-en.h	Sat Nov  4 02:51:30 2006
@@ -1836,9 +1836,11 @@
 #define MSGTR_RADIO_SetFreqFailed "[radio] ioctl set frequency 0x%x (%.2f) failed: %s\n"
 #define MSGTR_RADIO_GetFreqFailed "[radio] ioctl get frequency failed: %s\n"
 #define MSGTR_RADIO_SetMuteFailed "[radio] ioctl set mute failed: %s\n"
+#define MSGTR_RADIO_SetUnMuteFailed "[radio] ioctl set unmute failed: %s\n"
 #define MSGTR_RADIO_QueryControlFailed "[radio] ioctl query control failed: %s\n"
 #define MSGTR_RADIO_GetVolumeFailed "[radio] ioctl get volume failed: %s\n"
 #define MSGTR_RADIO_SetVolumeFailed "[radio] ioctl set volume failed: %s\n"
+#define MSGTR_RADIO_OpenMixerFailed "[radio] Warning: open mixer failed: %s\n"
 #define MSGTR_RADIO_DroppingFrame "\n[radio] too bad - dropping audio frame (%d bytes)!\n"
 #define MSGTR_RADIO_BufferEmpty "[radio] grab_audio_frame: buffer empty, waiting for %d data bytes.\n"
 #define MSGTR_RADIO_AudioInitFailed "[radio] audio_in_init failed: %s\n"
@@ -1862,4 +1864,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"
 
--- stream/stream_radio.c.orig	Tue Sep 12 01:41:45 2006
+++ stream/stream_radio.c	Sat Nov  4 02:51:43 2006
@@ -33,6 +33,22 @@
 #include <sys/ioctl.h>
 #include <errno.h>
 #include <unistd.h>
+
+#ifdef HAVE_RADIO_BSDBT848
+#include <sys/param.h>
+#if defined(__DragonFly__)
+#include <dev/video/meteor/ioctl_meteor.h>
+#include <dev/video/bktr/ioctl_bt848.h>
+#elif __FreeBSD_version >= 502100
+#include <dev/bktr/ioctl_meteor.h>
+#include <dev/bktr/ioctl_bt848.h>
+#else
+#include <machine/ioctl_meteor.h>
+#include <machine/ioctl_bt848.h>
+#endif
+
+#else // !BSDBT848
+
 #include <linux/types.h>
 
 #ifdef HAVE_RADIO_V4L2
@@ -44,6 +60,7 @@
 #warning  "V4L is deprecated and will be removed in future"
 #endif
 
+#endif //!BSDBT848
 
 
 #include "stream.h"
@@ -72,6 +89,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
@@ -82,7 +100,13 @@
 } radio_channels_t;
 
 /** (device,string, "/dev/radio0") name of radio device file */
+#ifdef HAVE_RADIO_BSDBT848
+char*   radio_param_device="/dev/tuner0";
+double freq_min = 87.50, freq_max = 108.00;
+int old_volume = 100;
+#else
 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) */
@@ -109,7 +133,9 @@
 
 typedef struct radio_priv_s {
     int                 radio_fd;          ///< radio device descriptor
+#ifndef HAVE_RADIO_BSDBT848
     int                 frac;              ///< fraction value (see comment to init_frac)
+#endif
     radio_channels_t*   radio_channel_list;
     radio_channels_t*   radio_channel_current;
     int                 driver;
@@ -185,7 +211,12 @@
 
             priv->radio_channel_current->freq=atof(tmp);
 
-            if (priv->radio_channel_current->freq == 0)
+            if ((priv->radio_channel_current->freq == 0)
+#ifdef HAVE_RADIO_BSDBT848
+		|| (priv->radio_channel_current->freq < freq_min)
+		|| (priv->radio_channel_current->freq > freq_max)
+#endif
+		)
                 mp_msg(MSGT_RADIO, MSGL_ERR, MSGTR_RADIO_WrongFreqForChannel,
                     priv->radio_channel_current->name);
 
@@ -507,7 +538,120 @@
     return STREAM_ERROR;
 }
 #endif //HAVE_RADIO_V4L
+#ifdef HAVE_RADIO_BSDBT848
+/*****************************************************************
+ * \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*100;
+    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;
+    }
+#ifdef USE_RADIO_CAPTURE
+    if(clear_buffer(priv)!=STREAM_OK){
+        mp_msg(MSGT_RADIO,MSGL_ERR,MSGTR_RADIO_ClearBufferFailed,
+							strerror(errno));
+        return  STREAM_ERROR;
+    }
+#endif
+    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)/100;
+    return STREAM_OK;
+}
+
+/*****************************************************************
+ * \brief set volume on radio card
+ * \param volume volume level (0..100)
+ * \return STREAM_OK if success, STREAM_ERROR otherwise
+ */
+static void set_volume_bsdbt848(radio_priv_t* priv,int volume){
+    int audio_flags, mixer_fd;
+
+    /*arg must be between 0 and 100*/
+    if (volume > 100) volume = 100;
+    if (volume < 0) volume = 0;
 
+    /* If volume = 0 mute radiodev, otherwise unmute and set volume */
+    if (volume == 0) {
+    	audio_flags = AUDIO_MUTE;
+    	if (ioctl(priv->radio_fd, BT848_SAUDIO, &audio_flags)<0){
+            mp_msg(MSGT_RADIO,MSGL_WARN,MSGTR_RADIO_SetMuteFailed,
+						strerror(errno));
+        }
+    }
+    else {
+    	audio_flags = AUDIO_UNMUTE;
+        if (ioctl(priv->radio_fd, BT848_SAUDIO, &audio_flags)<0){
+            mp_msg(MSGT_RADIO,MSGL_WARN,MSGTR_RADIO_SetUnMuteFailed,
+							strerror(errno));
+        }
+
+        if ((mixer_fd = open("/dev/mixer", O_RDWR)) < 0) {
+            mp_msg(MSGT_RADIO,MSGL_WARN,MSGTR_RADIO_OpenMixerFailed,
+							strerror(errno));
+        }
+
+        volume += (volume << 8);
+        if (ioctl(mixer_fd, MIXER_WRITE(SOUND_MIXER_LINE), &volume) < 0) {
+            mp_msg(MSGT_RADIO, MSGL_WARN,MSGTR_RADIO_SetVolumeFailed,
+							strerror(errno));
+        }
+        close(mixer_fd);
+    }
+}
+
+/*****************************************************************
+ * \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
+ */
+static int get_volume_bsdbt848(radio_priv_t* priv,int* volume){
+    int audio_flags, mixer_fd;
+
+    if ((mixer_fd = open("/dev/mixer", O_RDWR)) < 0) {
+        mp_msg(MSGT_RADIO,MSGL_WARN,MSGTR_RADIO_OpenMixerFailed,
+							strerror(errno));
+        return STREAM_ERROR;
+    }
+
+    if (ioctl(mixer_fd, MIXER_READ(SOUND_MIXER_LINE), volume) < 0) {
+        mp_msg(MSGT_RADIO, MSGL_ERR, MSGTR_RADIO_GetVolumeFailed,
+							strerror(errno));
+        return STREAM_ERROR;
+    }
+
+    *volume = *volume & 0x7f;
+
+    /*arg must be between 0 and 100*/
+    if (*volume > 100) *volume = 100;
+    if (*volume < 0) *volume = 0;
+
+    close(mixer_fd);
+    return STREAM_OK;
+}
+#endif //HAVE_RADIO_BSDBT848
+
+#ifndef HAVE_RADIO_BSDBT848
 static inline int init_frac(radio_priv_t* priv){ 
     switch(priv->driver){
 #ifdef HAVE_RADIO_V4L
@@ -522,6 +666,8 @@
     mp_msg(MSGT_RADIO,MSGL_ERR,MSGTR_RADIO_DriverUnknownId,priv->driver);
     return STREAM_ERROR;
 }
+#endif // !HAVE_RADIO_BSDBT848
+
 static inline int set_frequency(radio_priv_t* priv,float frequency){ 
     switch(priv->driver){
 #ifdef HAVE_RADIO_V4L
@@ -532,6 +678,10 @@
         case RADIO_DRIVER_V4L2:
             return set_frequency_v4l2(priv,frequency);
 #endif
+#ifdef HAVE_RADIO_BSDBT848
+        case RADIO_DRIVER_BSDBT848:
+            return set_frequency_bsdbt848(priv,frequency);
+#endif
     }
     mp_msg(MSGT_RADIO,MSGL_ERR,MSGTR_RADIO_DriverUnknownId,priv->driver);
     return STREAM_ERROR;
@@ -546,6 +696,10 @@
         case RADIO_DRIVER_V4L2:
             return get_frequency_v4l2(priv,frequency);
 #endif
+#ifdef HAVE_RADIO_BSDBT848
+        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;
@@ -562,6 +716,11 @@
             set_volume_v4l2(priv,volume);
             return;
 #endif
+#ifdef HAVE_RADIO_BSDBT848
+        case RADIO_DRIVER_BSDBT848:
+            set_volume_bsdbt848(priv,volume);
+            return;
+#endif
     }
     mp_msg(MSGT_RADIO,MSGL_ERR,MSGTR_RADIO_DriverUnknownId,priv->driver);
 }
@@ -575,6 +734,10 @@
         case RADIO_DRIVER_V4L2:
             return get_volume_v4l2(priv,volume);
 #endif
+#ifdef HAVE_RADIO_BSDBT848
+        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;
@@ -965,8 +1128,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(HAVE_RADIO_BSDBT848)
+        priv->driver=RADIO_DRIVER_BSDBT848;
 #else
         priv->driver=RADIO_DRIVER_V4L;
 #endif
@@ -981,6 +1146,11 @@
         priv->driver=RADIO_DRIVER_V4L;
     else
 #endif
+#ifdef HAVE_RADIO_BSDBT848
+    if (strncmp(radio_param_driver,"bsdbt848",8)==0)
+        priv->driver=RADIO_DRIVER_BSDBT848;
+    else
+#endif
     priv->driver=RADIO_DRIVER_UNKNOWN;
 
 
@@ -991,6 +1161,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);
@@ -1010,7 +1183,13 @@
     stream->close=close_s;
     stream->fill_buffer=fill_buffer_s;
 
-    priv->radio_fd = open(radio_param_device, O_RDWR);
+    priv->radio_fd = open(radio_param_device,
+#ifdef HAVE_RADIO_BSDBT848
+					O_RDONLY);
+#else
+					O_RDWR);
+#endif
+
     if (priv->radio_fd < 0) {
         mp_msg(MSGT_RADIO, MSGL_ERR, MSGTR_RADIO_UnableOpenDevice,
             radio_param_device, strerror(errno));
@@ -1020,19 +1199,28 @@
     mp_msg(MSGT_RADIO, MSGL_V, MSGTR_RADIO_RadioDevice, priv->radio_fd,radio_param_device);
     fcntl(priv->radio_fd, F_SETFD, FD_CLOEXEC);
 
+#ifdef HAVE_RADIO_BSDBT848
+    get_volume(priv, &old_volume);
+#endif
     set_volume(priv,0);
 
+#ifndef HAVE_RADIO_BSDBT848
     if (init_frac(priv)!=STREAM_OK){
         close_s(stream);
         return STREAM_ERROR;
     };
+#endif
 
     if (parse_channels(priv,p->radio_param_freq_channel,&frequency)!=STREAM_OK){
         close_s(stream);
         return STREAM_ERROR;
     }
 
-    if (frequency==0){
+    if (frequency==0
+#ifdef HAVE_RADIO_BSDBT848
+		     || (frequency < freq_min) || (frequency > freq_max)
+#endif
+		     ){
         mp_msg(MSGT_RADIO, MSGL_ERR, MSGTR_RADIO_WrongFreq,frequency);
         close_s(stream);
         return STREAM_ERROR;
@@ -1093,6 +1281,9 @@
     priv->radio_channel_current=NULL;
     priv->radio_channel_list=NULL;
 
+#ifdef HAVE_RADIO_BSDBT848
+    set_volume(priv, old_volume);
+#endif
     if (priv->radio_fd>0){
         close(priv->radio_fd);
     }


More information about the MPlayer-dev-eng mailing list