diff --git a/DOCS/man/en/mplayer.1 b/DOCS/man/en/mplayer.1 index 9efc6790d6..296237dd79 100644 --- a/DOCS/man/en/mplayer.1 +++ b/DOCS/man/en/mplayer.1 @@ -1616,12 +1616,16 @@ problems, which makes this process uncomfortable. Available options are: .RSs .IPs device= -Radio device to use (default: /dev/radio0). +Radio device to use (default: /dev/radio0 for Linux and /dev/tuner0 for *BSD). .IPs driver= 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= (*BSD BT848 only) +minimum allowed frequency (default: 87.50) +.IPs freq_max= (*BSD BT848 only) +maximum allowed frequency (default: 108.00) .IPs channels=\-,\-,... Set channel list. Use _ for spaces in names (or play with quoting ;-). diff --git a/cfg-common.h b/cfg-common.h index 46350465af..6f8bf086e6 100644 --- a/cfg-common.h +++ b/cfg-common.h @@ -394,6 +394,10 @@ extern char* edl_output_filename; 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}, diff --git a/configure b/configure index c2f330b1c5..c50f45c810 100755 --- a/configure +++ b/configure @@ -228,6 +228,7 @@ Optional features: --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=no _radio_capture=no _radio_v4l=auto _radio_v4l2=auto +_radio_bsdbt848=auto _tv=yes _tv_v4l1=auto _tv_v4l2=auto @@ -1904,6 +1906,8 @@ for ac_option do --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 @@ else 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 < +#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 @@ $_def_radio_v4l /* 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 diff --git a/help/help_mp-en.h b/help/help_mp-en.h index b56da8a431..ab9084d178 100644 --- a/help/help_mp-en.h +++ b/help/help_mp-en.h @@ -1960,4 +1960,5 @@ static char help_text[]= #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" diff --git a/stream/stream_radio.c b/stream/stream_radio.c index 6010bf12f3..bb19aa4fd7 100644 --- a/stream/stream_radio.c +++ b/stream/stream_radio.c @@ -33,6 +33,13 @@ #include #include #include + +#ifdef RADIO_BSDBT848_HDR +#include +#include RADIO_BSDBT848_HDR + +#else // RADIO_BSDBT848_HDR + #include #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 @@ typedef struct radio_channels_s { 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 @@ static int get_volume_v4l(radio_priv_t* priv,int* volume){ 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){ @@ -517,6 +635,10 @@ static inline int init_frac(radio_priv_t* priv){ #ifdef HAVE_RADIO_V4L2 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); @@ -539,6 +661,12 @@ static inline int set_frequency(radio_priv_t* priv,float frequency){ if(set_frequency_v4l2(priv,frequency)!=STREAM_OK) 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); @@ -561,6 +689,10 @@ static inline int get_frequency(radio_priv_t* priv,float* frequency){ #ifdef HAVE_RADIO_V4L2 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); @@ -577,6 +709,11 @@ static inline void set_volume(radio_priv_t* priv,int volume){ case RADIO_DRIVER_V4L2: 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); @@ -590,6 +727,10 @@ static inline int get_volume(radio_priv_t* priv,int* volume){ #ifdef HAVE_RADIO_V4L2 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); @@ -996,8 +1137,10 @@ static int open_s(stream_t *stream,int mode, void* opts, int* file_format) { 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 @@ -1011,6 +1154,11 @@ static int open_s(stream_t *stream,int mode, void* opts, int* file_format) { if (strncmp(radio_param_driver,"v4l",3)==0) 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 @@ static int open_s(stream_t *stream,int mode, void* opts, int* file_format) { 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); diff --git a/stream/stream_radio.h b/stream/stream_radio.h index 37cb665341..3baca729a0 100644 --- a/stream/stream_radio.h +++ b/stream/stream_radio.h @@ -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;