4 * Initially wrote by Vladimir Voroshilov <voroshil@univer.omsk.su>.
5 * Based on tv.c and tvi_v4l2.c code.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 * * Listening v4l compatible radio cards using line-in or
25 * * Grabbing audio data using -ao pcm or -dumpaudio
26 * (must be compiled with --enable-radio-capture).
33 #include <sys/ioctl.h>
37 #ifdef HAVE_RADIO_BSDBT848
38 #include <sys/param.h>
39 #ifdef IOCTL_BT848_H_NAME
40 #include IOCTL_BT848_H_NAME
43 #else // HAVE_RADIO_BSDBT848
45 #include <linux/types.h>
47 #ifdef HAVE_RADIO_V4L2
48 #include <linux/videodev2.h>
52 #include <linux/videodev.h>
53 #warning "V4L is deprecated and will be removed in future"
56 #endif // !IOCTL_BT848_H_NAME
60 #include "libmpdemux/demuxer.h"
65 #include "stream_radio.h"
66 #include "libavutil/avstring.h"
68 #ifdef USE_RADIO_CAPTURE
71 #ifdef HAVE_SYS_SOUNDCARD_H
72 #include <sys/soundcard.h>
74 #ifdef HAVE_SOUNDCARD_H
75 #include <soundcard.h>
77 #include <linux/soundcard.h>
83 typedef struct radio_channels_s
{
84 int index
; ///< channel index in channels list
85 float freq
; ///< frequency in MHz
86 char name
[20]; ///< channel name
87 struct radio_channels_s
* next
;
88 struct radio_channels_s
* prev
;
91 /// default values for options
92 radio_param_t stream_radio_defaults
={
93 #ifdef HAVE_RADIO_BSDBT848
94 "/dev/tuner0", //device
98 "/dev/radio0", //device;
110 typedef struct radio_priv_s
{
111 int radio_fd
; ///< radio device descriptor
112 int frac
; ///< fraction value (see comment to init_frac)
113 radio_channels_t
* radio_channel_list
;
114 radio_channels_t
* radio_channel_current
;
115 float rangelow
; ///< lowest tunable frequency in MHz
116 float rangehigh
; ///< highest tunable frequency in MHz
117 const struct radio_driver_s
* driver
;
119 #ifdef USE_RADIO_CAPTURE
120 volatile int do_capture
; ///< is capture enabled
122 unsigned char* audio_ringbuffer
;
123 int audio_head
; ///< start of meanfull data in ringbuffer
124 int audio_tail
; ///< end of meanfull data in ringbuffer
125 int audio_buffer_size
; ///< size of ringbuffer
126 int audio_cnt
; ///< size of meanfull data inringbuffer
127 int audio_drop
; ///< number of dropped bytes
130 radio_param_t
*radio_param
;
133 typedef struct radio_driver_s
{
136 int (*init_frac
)(radio_priv_t
* priv
);
137 void (*set_volume
)(radio_priv_t
* priv
,int volume
);
138 int (*get_volume
)(radio_priv_t
* priv
,int* volume
);
139 int (*set_frequency
)(radio_priv_t
* priv
,float frequency
);
140 int (*get_frequency
)(radio_priv_t
* priv
,float* frequency
);
143 #define ST_OFF(f) M_ST_OFF(radio_param_t,f)
144 static m_option_t stream_opts_fields
[] = {
145 {"hostname", ST_OFF(freq_channel
), CONF_TYPE_FLOAT
, 0, 0 ,0, NULL
},
146 {"filename", ST_OFF(capture
), CONF_TYPE_STRING
, 0, 0 ,0, NULL
},
147 { NULL
, NULL
, 0, 0, 0, 0, NULL
}
150 static struct m_struct_st stream_opts
= {
152 sizeof(radio_param_t
),
153 &stream_radio_defaults
,
157 static void close_s(struct stream_st
* stream
);
158 #ifdef USE_RADIO_CAPTURE
159 static int clear_buffer(radio_priv_t
* priv
);
163 /*****************************************************************
164 * \brief parse channels parameter and store result into list
165 * \param freq_channel if channels!=NULL this mean channel number, otherwise - frequency
166 * \param pfreq selected frequency (from selected channel or from URL)
167 * \result STREAM_OK if success, STREAM_ERROR otherwise
169 * channels option must be in the following format
170 * <frequency>-<name>,<frequency>-<name>,...
172 * '_' will be replaced with spaces.
174 * If channels option is not null, number in movie URL will be treated as
175 * channel position in channel list.
177 static int parse_channels(radio_priv_t
* priv
,float freq_channel
,float* pfreq
){
181 if (priv
->radio_param
->channels
){
182 /*parsing channels string*/
183 channels
=priv
->radio_param
->channels
;
185 mp_msg(MSGT_RADIO
, MSGL_INFO
, MSGTR_RADIO_ChannelNamesDetected
);
186 priv
->radio_channel_list
= malloc(sizeof(radio_channels_t
));
187 priv
->radio_channel_list
->index
=1;
188 priv
->radio_channel_list
->next
=NULL
;
189 priv
->radio_channel_list
->prev
=NULL
;
190 priv
->radio_channel_current
= priv
->radio_channel_list
;
193 char* tmp
= *(channels
++);
194 char* sep
= strchr(tmp
,'-');
195 if (!sep
) continue; // Wrong syntax, but mplayer should not crash
196 av_strlcpy(priv
->radio_channel_current
->name
, sep
+ 1,sizeof(priv
->radio_channel_current
->name
)-1);
200 priv
->radio_channel_current
->freq
=atof(tmp
);
202 if ((priv
->radio_channel_current
->freq
>priv
->rangehigh
)||(priv
->radio_channel_current
->freq
<priv
->rangelow
))
203 mp_msg(MSGT_RADIO
, MSGL_ERR
, MSGTR_RADIO_WrongFreqForChannel
,
204 priv
->radio_channel_current
->name
);
206 while ((sep
=strchr(priv
->radio_channel_current
->name
, '_'))) sep
[0] = ' ';
208 priv
->radio_channel_current
->next
= malloc(sizeof(radio_channels_t
));
209 priv
->radio_channel_current
->next
->index
= priv
->radio_channel_current
->index
+ 1;
210 priv
->radio_channel_current
->next
->prev
= priv
->radio_channel_current
;
211 priv
->radio_channel_current
->next
->next
= NULL
;
212 priv
->radio_channel_current
= priv
->radio_channel_current
->next
;
214 if (priv
->radio_channel_current
->prev
)
215 priv
->radio_channel_current
->prev
->next
= NULL
;
216 free(priv
->radio_channel_current
);
219 channel
= freq_channel
;
223 priv
->radio_channel_current
= priv
->radio_channel_list
;
224 for (i
= 1; i
< channel
; i
++)
225 if (priv
->radio_channel_current
->next
)
226 priv
->radio_channel_current
= priv
->radio_channel_current
->next
;
227 if (priv
->radio_channel_current
->index
!=channel
){
228 if (((float)((int)freq_channel
))!=freq_channel
)
229 mp_msg(MSGT_RADIO
, MSGL_ERR
, MSGTR_RADIO_WrongChannelNumberFloat
,freq_channel
);
231 mp_msg(MSGT_RADIO
, MSGL_ERR
, MSGTR_RADIO_WrongChannelNumberInt
,(int)freq_channel
);
234 mp_msg(MSGT_RADIO
, MSGL_INFO
, MSGTR_RADIO_SelectedChannel
, priv
->radio_channel_current
->index
,
235 priv
->radio_channel_current
->name
, priv
->radio_channel_current
->freq
);
236 *pfreq
=priv
->radio_channel_current
->freq
;
239 mp_msg(MSGT_RADIO
, MSGL_INFO
, MSGTR_RADIO_FreqParameterDetected
);
240 priv
->radio_channel_list
=malloc(sizeof(radio_channels_t
));
241 priv
->radio_channel_list
->next
=NULL
;
242 priv
->radio_channel_list
->prev
=NULL
;
243 priv
->radio_channel_list
->index
=1;
244 snprintf(priv
->radio_channel_list
->name
,sizeof(priv
->radio_channel_current
->name
)-1,"Freq: %.2f",freq_channel
);
246 priv
->radio_channel_current
=priv
->radio_channel_list
;
250 mp_msg(MSGT_RADIO
, MSGL_DBG2
, MSGTR_RADIO_DoneParsingChannels
);
254 #ifdef HAVE_RADIO_V4L2
255 /*****************************************************************
256 * \brief get fraction value for using in set_frequency and get_frequency
257 * \return STREAM_OK if success, STREAM_ERROR otherwise
259 * V4L2_TUNER_CAP_LOW:
261 * frac= 1MHz/unit=1000000/62.5 =16000
265 * frac= 1MHz/unit=1000000/62500 =16
267 static int init_frac_v4l2(radio_priv_t
* priv
){
268 struct v4l2_tuner tuner
;
270 memset(&tuner
,0,sizeof(tuner
));
272 if (ioctl(priv
->radio_fd
, VIDIOC_G_TUNER
, &tuner
)<0){
273 mp_msg(MSGT_RADIO
,MSGL_WARN
,MSGTR_RADIO_GetTunerFailed
,strerror(errno
),priv
->frac
);
276 if(tuner
.type
!=V4L2_TUNER_RADIO
){
277 mp_msg(MSGT_RADIO
,MSGL_ERR
,MSGTR_RADIO_NotRadioDevice
,priv
->radio_param
->device
);
280 if(tuner
.capability
& V4L2_TUNER_CAP_LOW
){
282 mp_msg(MSGT_RADIO
,MSGL_DBG2
,MSGTR_RADIO_TunerCapLowYes
,priv
->frac
);
286 mp_msg(MSGT_RADIO
,MSGL_DBG2
,MSGTR_RADIO_TunerCapLowNo
,priv
->frac
);
289 priv
->rangelow
=((float)tuner
.rangelow
)/priv
->frac
;
290 priv
->rangehigh
=((float)tuner
.rangehigh
)/priv
->frac
;
291 mp_msg(MSGT_RADIO
,MSGL_V
,MSGTR_RADIO_FreqRange
,priv
->rangelow
,priv
->rangehigh
);
295 /*****************************************************************
296 * \brief tune card to given frequency
297 * \param frequency frequency in MHz
298 * \return STREAM_OK if success, STREAM_ERROR otherwise
300 static int set_frequency_v4l2(radio_priv_t
* priv
,float frequency
){
301 struct v4l2_frequency freq
;
303 memset(&freq
,0,sizeof(freq
));
305 freq
.type
=V4L2_TUNER_RADIO
;
306 freq
.frequency
=frequency
*priv
->frac
;
307 if(ioctl(priv
->radio_fd
,VIDIOC_S_FREQUENCY
,&freq
)<0){
308 mp_msg(MSGT_RADIO
,MSGL_ERR
,MSGTR_RADIO_SetFreqFailed
,freq
.frequency
,
309 frequency
,strerror(errno
));
315 /*****************************************************************
316 * \brief get current tuned frequency from card
317 * \param frequency where to store frequency in MHz
318 * \return STREAM_OK if success, STREAM_ERROR otherwise
320 static int get_frequency_v4l2(radio_priv_t
* priv
,float* frequency
){
321 struct v4l2_frequency freq
;
322 memset(&freq
,0,sizeof(freq
));
323 if (ioctl(priv
->radio_fd
, VIDIOC_G_FREQUENCY
, &freq
) < 0) {
324 mp_msg(MSGT_RADIO
,MSGL_ERR
,MSGTR_RADIO_GetFreqFailed
,strerror(errno
));
327 *frequency
=((float)freq
.frequency
)/priv
->frac
;
331 /*****************************************************************
332 * \brief set volume on radio card
333 * \param volume volume level (0..100)
334 * \return STREAM_OK if success, STREAM_ERROR otherwise
336 static void set_volume_v4l2(radio_priv_t
* priv
,int volume
){
337 struct v4l2_queryctrl qctrl
;
338 struct v4l2_control control
;
340 /*arg must be between 0 and 100*/
341 if (volume
> 100) volume
= 100;
342 if (volume
< 0) volume
= 0;
344 memset(&control
,0,sizeof(control
));
345 control
.id
=V4L2_CID_AUDIO_MUTE
;
346 control
.value
= (volume
==0?1:0);
347 if (ioctl(priv
->radio_fd
, VIDIOC_S_CTRL
, &control
)<0){
348 mp_msg(MSGT_RADIO
,MSGL_WARN
,MSGTR_RADIO_SetMuteFailed
,strerror(errno
));
351 memset(&qctrl
,0,sizeof(qctrl
));
352 qctrl
.id
= V4L2_CID_AUDIO_VOLUME
;
353 if (ioctl(priv
->radio_fd
, VIDIOC_QUERYCTRL
, &qctrl
) < 0) {
354 mp_msg(MSGT_RADIO
, MSGL_WARN
, MSGTR_RADIO_QueryControlFailed
,strerror(errno
));
358 memset(&control
,0,sizeof(control
));
359 control
.id
=V4L2_CID_AUDIO_VOLUME
;
360 control
.value
=qctrl
.minimum
+volume
*(qctrl
.maximum
-qctrl
.minimum
)/100;
361 if (ioctl(priv
->radio_fd
, VIDIOC_S_CTRL
, &control
) < 0) {
362 mp_msg(MSGT_RADIO
, MSGL_WARN
,MSGTR_RADIO_SetVolumeFailed
,strerror(errno
));
366 /*****************************************************************
367 * \brief get current volume from radio card
368 * \param volume where to store volume level (0..100)
369 * \return STREAM_OK if success, STREAM_ERROR otherwise
371 static int get_volume_v4l2(radio_priv_t
* priv
,int* volume
){
372 struct v4l2_queryctrl qctrl
;
373 struct v4l2_control control
;
375 memset(&qctrl
,0,sizeof(qctrl
));
376 qctrl
.id
= V4L2_CID_AUDIO_VOLUME
;
377 if (ioctl(priv
->radio_fd
, VIDIOC_QUERYCTRL
, &qctrl
) < 0) {
378 mp_msg(MSGT_RADIO
, MSGL_ERR
, MSGTR_RADIO_QueryControlFailed
,strerror(errno
));
382 memset(&control
,0,sizeof(control
));
383 control
.id
=V4L2_CID_AUDIO_VOLUME
;
384 if (ioctl(priv
->radio_fd
, VIDIOC_G_CTRL
, &control
) < 0) {
385 mp_msg(MSGT_RADIO
, MSGL_ERR
,MSGTR_RADIO_GetVolumeFailed
,strerror(errno
));
389 if (qctrl
.maximum
==qctrl
.minimum
)
390 *volume
=qctrl
.minimum
;
392 *volume
=100*(control
.value
-qctrl
.minimum
)/(qctrl
.maximum
-qctrl
.minimum
);
394 /*arg must be between 0 and 100*/
395 if (*volume
> 100) *volume
= 100;
396 if (*volume
< 0) *volume
= 0;
401 /* v4l2 driver info structure */
402 static const radio_driver_t radio_driver_v4l2
={
404 MSGTR_RADIO_DriverV4L2
,
411 #endif //HAVE_RADIO_V4L2
412 #ifdef HAVE_RADIO_V4L
413 /*****************************************************************
414 * \brief get fraction value for using in set_frequency and get_frequency
415 * \return STREAM_OK if success, STREAM_ERROR otherwise
417 * V4L2_TUNER_CAP_LOW:
419 * frac= 1MHz/unit=1000000/62.5 =16000
423 * frac= 1MHz/unit=1000000/62500 =16
426 static int init_frac_v4l(radio_priv_t
* priv
){
427 struct video_tuner tuner
;
428 memset(&tuner
,0,sizeof(tuner
));
429 if (ioctl(priv
->radio_fd
, VIDIOCGTUNER
, &tuner
) <0){
430 mp_msg(MSGT_RADIO
,MSGL_WARN
,MSGTR_RADIO_GetTunerFailed
,strerror(errno
),priv
->frac
);
433 if(tuner
.flags
& VIDEO_TUNER_LOW
){
435 mp_msg(MSGT_RADIO
,MSGL_DBG2
,MSGTR_RADIO_TunerCapLowYes
,priv
->frac
);
438 mp_msg(MSGT_RADIO
,MSGL_DBG2
,MSGTR_RADIO_TunerCapLowNo
,priv
->frac
);
441 priv
->rangelow
=((float)tuner
.rangelow
)/priv
->frac
;
442 priv
->rangehigh
=((float)tuner
.rangehigh
)/priv
->frac
;
443 mp_msg(MSGT_RADIO
,MSGL_V
,MSGTR_RADIO_FreqRange
,priv
->rangelow
,priv
->rangehigh
);
448 /*****************************************************************
449 * \brief tune card to given frequency
450 * \param frequency frequency in MHz
451 * \return STREAM_OK if success, STREAM_ERROR otherwise
453 static int set_frequency_v4l(radio_priv_t
* priv
,float frequency
){
455 freq
=frequency
*priv
->frac
;
456 if (ioctl(priv
->radio_fd
, VIDIOCSFREQ
, &freq
) < 0) {
457 mp_msg(MSGT_RADIO
,MSGL_ERR
,MSGTR_RADIO_SetFreqFailed
,freq
,frequency
,strerror(errno
));
462 /*****************************************************************
463 * \brief get current tuned frequency from card
464 * \param frequency where to store frequency in MHz
465 * \return STREAM_OK if success, STREAM_ERROR otherwise
467 static int get_frequency_v4l(radio_priv_t
* priv
,float* frequency
){
469 if (ioctl(priv
->radio_fd
, VIDIOCGFREQ
, &freq
) < 0) {
470 mp_msg(MSGT_RADIO
,MSGL_ERR
,MSGTR_RADIO_GetFreqFailed
,strerror(errno
));
473 *frequency
=((float)freq
)/priv
->frac
;
477 /*****************************************************************
478 * \brief set volume on radio card
479 * \param volume volume level (0..100)
480 * \return STREAM_OK if success, STREAM_ERROR otherwise
482 static void set_volume_v4l(radio_priv_t
* priv
,int volume
){
483 struct video_audio audio
;
485 /*arg must be between 0 and 100*/
486 if (volume
> 100) volume
= 100;
487 if (volume
< 0) volume
= 0;
489 memset(&audio
,0,sizeof(audio
));
490 audio
.flags
= (volume
==0?VIDEO_AUDIO_MUTE
:0);
491 if (ioctl(priv
->radio_fd
, VIDIOCSAUDIO
, &audio
)<0){
492 mp_msg(MSGT_RADIO
,MSGL_WARN
,MSGTR_RADIO_SetMuteFailed
,strerror(errno
));
495 memset(&audio
,0,sizeof(audio
));
496 audio
.flags
= VIDEO_AUDIO_VOLUME
;
497 audio
.mode
= VIDEO_SOUND_STEREO
;
499 audio
.volume
= volume
* (65535 / 100);
501 if (ioctl(priv
->radio_fd
, VIDIOCSAUDIO
, &audio
) < 0){
502 mp_msg(MSGT_RADIO
,MSGL_ERR
,MSGTR_RADIO_SetVolumeFailed
,strerror(errno
));
506 /*****************************************************************
507 * \brief get current volume from radio card
508 * \param volume where to store volume level (0..100)
509 * \return STREAM_OK if success, STREAM_ERROR otherwise
511 static int get_volume_v4l(radio_priv_t
* priv
,int* volume
){
512 struct video_audio audio
;
514 memset(&audio
,0,sizeof(audio
));
516 if (ioctl(priv
->radio_fd
, VIDIOCGAUDIO
, &audio
) < 0){
517 mp_msg(MSGT_RADIO
,MSGL_ERR
,MSGTR_RADIO_GetVolumeFailed
,strerror(errno
));
521 if (audio
.flags
& VIDEO_AUDIO_VOLUME
){
522 *volume
=100*audio
.volume
/65535;
523 /*arg must be between 0 and 100*/
524 if (*volume
> 100) *volume
= 100;
525 if (*volume
< 0) *volume
= 0;
532 /* v4l driver info structure */
533 static const radio_driver_t radio_driver_v4l
={
535 MSGTR_RADIO_DriverV4L
,
542 #endif //HAVE_RADIO_V4L
543 #ifdef HAVE_RADIO_BSDBT848
545 /*****************************************************************
546 * \brief get fraction value for using in set_frequency and get_frequency
547 * \return STREAM_OK if success, STREAM_ERROR otherwise
549 * For *BSD BT848 frac=100
551 * Here is a coment from FreeBSD 5.2-RELEASE source code:
554 * * Programming the tuner properly is quite complicated.
555 * * Here are some notes, based on a FM1246 data sheet for a PAL-I tuner.
556 * * The tuner (front end) covers 45.75 MHz - 855.25 MHz and an FM band of
557 * * 87.5 MHz to 108.0 MHz.
559 * Thus, frequency range is limited to 87.5-108.0, but you can change
560 * it, using freq_min and freq_max options
562 static int init_frac_bsdbt848(radio_priv_t
* priv
){
564 priv
->rangelow
=priv
->radio_param
->freq_min
;
565 priv
->rangehigh
=priv
->radio_param
->freq_max
;
569 /*****************************************************************
570 * \brief tune card to given frequency
571 * \param frequency frequency in MHz
572 * \return STREAM_OK if success, STREAM_ERROR otherwise
574 static int set_frequency_bsdbt848(radio_priv_t
* priv
,float frequency
){
576 freq
=frequency
*priv
->frac
;
577 if(ioctl(priv
->radio_fd
,RADIO_SETFREQ
,&freq
)<0){
578 mp_msg(MSGT_RADIO
,MSGL_ERR
,MSGTR_RADIO_SetFreqFailed
,freq
, frequency
, strerror(errno
));
584 /*****************************************************************
585 * \brief get current tuned frequency from card
586 * \param frequency where to store frequency in MHz
587 * \return STREAM_OK if success, STREAM_ERROR otherwise
589 static int get_frequency_bsdbt848(radio_priv_t
* priv
,float* frequency
){
591 if (ioctl(priv
->radio_fd
, RADIO_GETFREQ
, &freq
) < 0) {
592 mp_msg(MSGT_RADIO
,MSGL_ERR
,MSGTR_RADIO_GetFreqFailed
,strerror(errno
));
595 *frequency
=((float)freq
)/priv
->frac
;
599 /*****************************************************************
600 * \brief set volume on radio card
601 * \param volume volume level (0..100)
602 * \return STREAM_OK if success, STREAM_ERROR otherwise
604 * *BSD BT848 does not have volume changing abilities, so
605 * we will just mute sound if volume=0 and unmute it otherwise.
607 static void set_volume_bsdbt848(radio_priv_t
* priv
,int volume
){
610 /*arg must be between 0 and 100*/
611 if (volume
> 100) volume
= 100;
612 if (volume
< 0) volume
= 0;
614 audio_flags
= (volume
==0?AUDIO_MUTE
:AUDIO_UNMUTE
);
615 if (ioctl(priv
->radio_fd
, BT848_SAUDIO
, &audio_flags
)<0){
616 mp_msg(MSGT_RADIO
,MSGL_WARN
,MSGTR_RADIO_SetMuteFailed
,strerror(errno
));
620 /*****************************************************************
621 * \brief get current volume from radio card
622 * \param volume where to store volume level (0..100)
623 * \return previous STREAM_OK if success, STREAM_ERROR otherwise
625 * *BSD BT848 does not have volume changing abilities, so
626 * we will return 0 if sound is muted and 100 otherwise.
628 static int get_volume_bsdbt848(radio_priv_t
* priv
,int* volume
){
631 if (ioctl(priv
->radio_fd
, BT848_GAUDIO
, &audio_flags
)<0){
632 mp_msg(MSGT_RADIO
,MSGL_ERR
,MSGTR_RADIO_GetVolumeFailed
,strerror(errno
));
636 if (audio_flags
& AUDIO_MUTE
)
644 /* bsdbt848 driver info structure */
645 static const radio_driver_t radio_driver_bsdbt848
={
647 MSGTR_RADIO_DriverBSDBT848
,
651 set_frequency_bsdbt848
,
652 get_frequency_bsdbt848
654 #endif //HAVE_RADIO_BSDBT848
656 static inline int init_frac(radio_priv_t
* priv
){
657 return priv
->driver
->init_frac(priv
);
659 static inline int set_frequency(radio_priv_t
* priv
,float frequency
){
660 if ((frequency
<priv
->rangelow
)||(frequency
>priv
->rangehigh
)){
661 mp_msg(MSGT_RADIO
,MSGL_ERR
,MSGTR_RADIO_WrongFreq
,frequency
);
664 if(priv
->driver
->set_frequency(priv
,frequency
)!=STREAM_OK
)
667 #ifdef USE_RADIO_CAPTURE
668 if(clear_buffer(priv
)!=STREAM_OK
){
669 mp_msg(MSGT_RADIO
,MSGL_ERR
,MSGTR_RADIO_ClearBufferFailed
,strerror(errno
));
675 static inline int get_frequency(radio_priv_t
* priv
,float* frequency
){
676 return priv
->driver
->get_frequency(priv
,frequency
);
678 static inline void set_volume(radio_priv_t
* priv
,int volume
){
679 priv
->driver
->set_volume(priv
,volume
);
681 static inline int get_volume(radio_priv_t
* priv
,int* volume
){
682 return priv
->driver
->get_volume(priv
,volume
);
686 #ifndef USE_RADIO_CAPTURE
687 /*****************************************************************
688 * \brief stub, if capture disabled at compile-time
691 static inline int init_audio(radio_priv_t
*priv
){ return STREAM_OK
;}
693 /*****************************************************************
694 * \brief making buffer empty
695 * \return STREAM_OK if success, STREAM_ERROR otherwise
697 * when changing channel we must clear buffer to avoid large switching delay
699 static int clear_buffer(radio_priv_t
* priv
){
700 if (!priv
->do_capture
) return STREAM_OK
;
701 priv
->audio_tail
= 0;
702 priv
->audio_head
= 0;
704 memset(priv
->audio_ringbuffer
,0,priv
->audio_in
.blocksize
);
707 /*****************************************************************
708 * \brief read next part of data into buffer
709 * \return -1 if error occured or no data available yet, otherwise - bytes read
710 * NOTE: audio device works in non-blocking mode
712 static int read_chunk(audio_in_t
*ai
, unsigned char *buffer
)
717 #if defined(HAVE_ALSA9) || defined(HAVE_ALSA1X)
719 //device opened in non-blocking mode
720 ret
= snd_pcm_readi(ai
->alsa
.handle
, buffer
, ai
->alsa
.chunk_size
);
721 if (ret
!= ai
->alsa
.chunk_size
) {
723 if (ret
==-EAGAIN
) return -1;
724 mp_msg(MSGT_RADIO
, MSGL_ERR
, MSGTR_MPDEMUX_AUDIOIN_ErrReadingAudio
, snd_strerror(ret
));
726 if (ai_alsa_xrun(ai
) == 0) {
727 mp_msg(MSGT_RADIO
, MSGL_ERR
, MSGTR_MPDEMUX_AUDIOIN_XRUNSomeFramesMayBeLeftOut
);
729 mp_msg(MSGT_RADIO
, MSGL_ERR
, MSGTR_MPDEMUX_AUDIOIN_ErrFatalCannotRecover
);
733 mp_msg(MSGT_RADIO
, MSGL_ERR
, MSGTR_MPDEMUX_AUDIOIN_NotEnoughSamples
);
744 we must return exactly blocksize bytes, so if we have got any bytes
745 at first call to read, we will loop untils get all blocksize bytes
746 otherwise we will return -1
748 while(bt
<ai
->blocksize
){
749 //device opened in non-blocking mode
750 ret
= read(ai
->oss
.audio_fd
, buffer
+bt
, ai
->blocksize
-bt
);
751 if (ret
==ai
->blocksize
) return ret
;
753 if (errno
==EAGAIN
&& bt
==0) return -1; //no data avail yet
754 if (errno
==EAGAIN
) { usleep(1000); continue;} //nilling buffer to blocksize size
755 mp_msg(MSGT_RADIO
, MSGL_ERR
, MSGTR_MPDEMUX_AUDIOIN_ErrReadingAudio
, strerror(errno
));
767 /*****************************************************************
768 * \brief grab next frame from audio device
769 * \parameter buffer - store buffer
770 * \parameter len - store buffer size in bytes
771 * \return number of bytes written into buffer
773 * grabs len (or less) bytes from ringbuffer into buffer
774 * if ringbuffer is empty waits until len bytes of data will be available
776 * priv->audio_cnt - size (in bytes) of ringbuffer's filled part
777 * priv->audio_drop - size (in bytes) of dropped data (if no space in ringbuffer)
778 * priv->audio_head - index of first byte in filled part
779 * priv->audio_tail - index of last byte in filled part
781 * NOTE: audio_tail always aligned by priv->audio_in.blocksize
782 * audio_head may NOT.
784 static int grab_audio_frame(radio_priv_t
*priv
, char *buffer
, int len
)
787 mp_msg(MSGT_RADIO
, MSGL_DBG3
, MSGTR_RADIO_BufferString
,"grab_audio_frame",priv
->audio_cnt
,priv
->audio_drop
);
788 /* Cache buffer must be filled by some audio packets when playing starts.
789 Otherwise MPlayer will quit with EOF error.
790 Probably, there is need more carefull checking rather than simple 'for' loop
791 (something like timer or similar).
793 1000ms delay will happen only at first buffer filling. At next call function
794 just fills buffer until either buffer full or no data from driver available.
796 for (i
=0;i
<1000 && priv
->audio_cnt
<priv
->audio_buffer_size
; i
++){
797 //read_chunk fills exact priv->blocksize bytes
798 if(read_chunk(&priv
->audio_in
, priv
->audio_ringbuffer
+priv
->audio_tail
) < 0){
799 //sleppeing only when waiting first block to fill empty buffer
800 if (!priv
->audio_cnt
){
806 priv
->audio_cnt
+=priv
->audio_in
.blocksize
;
807 priv
->audio_tail
= (priv
->audio_tail
+priv
->audio_in
.blocksize
) % priv
->audio_buffer_size
;
809 if(priv
->audio_cnt
<len
)
811 memcpy(buffer
, priv
->audio_ringbuffer
+priv
->audio_head
,len
);
812 priv
->audio_head
= (priv
->audio_head
+len
) % priv
->audio_buffer_size
;
813 priv
->audio_cnt
-=len
;
816 /*****************************************************************
817 * \brief init audio device
818 * \return STREAM_OK if success, STREAM_ERROR otherwise
820 static int init_audio(radio_priv_t
*priv
)
825 if (priv
->audio_inited
) return 1;
827 /* do_capture==0 mplayer was not started with capture keyword, so disabling capture*/
828 if(!priv
->do_capture
)
831 if (!priv
->radio_param
->adevice
){
837 mp_msg(MSGT_RADIO
,MSGL_V
,MSGTR_RADIO_CaptureStarting
);
838 #if defined(HAVE_ALSA9) || defined(HAVE_ALSA1X)
839 while ((tmp
= strrchr(priv
->radio_param
->adevice
, '='))){
841 //adevice option looks like ALSA device name. Switching to ALSA
844 while ((tmp
= strrchr(priv
->radio_param
->adevice
, '.')))
848 if(audio_in_init(&priv
->audio_in
, is_oss
?AUDIO_IN_OSS
:AUDIO_IN_ALSA
)<0){
849 mp_msg(MSGT_RADIO
, MSGL_ERR
, MSGTR_RADIO_AudioInInitFailed
);
852 audio_in_set_device(&priv
->audio_in
, priv
->radio_param
->adevice
);
853 audio_in_set_channels(&priv
->audio_in
, priv
->radio_param
->achannels
);
854 audio_in_set_samplerate(&priv
->audio_in
, priv
->radio_param
->arate
);
856 if (audio_in_setup(&priv
->audio_in
) < 0) {
857 mp_msg(MSGT_RADIO
, MSGL_ERR
, MSGTR_RADIO_AudioInSetupFailed
, strerror(errno
));
861 ioctl(priv
->audio_in
.oss
.audio_fd
, SNDCTL_DSP_NONBLOCK
, 0);
862 #if defined(HAVE_ALSA9) || defined(HAVE_ALSA1X)
864 snd_pcm_nonblock(priv
->audio_in
.alsa
.handle
,1);
868 priv
->audio_buffer_size
= seconds
*priv
->audio_in
.samplerate
*priv
->audio_in
.channels
*
869 priv
->audio_in
.bytes_per_sample
+priv
->audio_in
.blocksize
;
870 if (priv
->audio_buffer_size
< 256*priv
->audio_in
.blocksize
)
871 priv
->audio_buffer_size
= 256*priv
->audio_in
.blocksize
;
872 mp_msg(MSGT_RADIO
, MSGL_V
, MSGTR_RADIO_AudioBuffer
,
873 priv
->audio_buffer_size
,priv
->audio_in
.blocksize
);
875 priv
->audio_ringbuffer
= calloc(1, priv
->audio_buffer_size
);
876 if (!priv
->audio_ringbuffer
) {
877 mp_msg(MSGT_RADIO
, MSGL_ERR
, MSGTR_RADIO_AllocateBufferFailed
,priv
->audio_in
.blocksize
, priv
->audio_buffer_size
, strerror(errno
));
880 priv
->audio_head
= 0;
881 priv
->audio_tail
= 0;
883 priv
->audio_drop
= 0;
886 priv
->audio_inited
= 1;
890 #endif //USE_RADIO_CAPTURE
892 /*-------------------------------------------------------------------------
893 for call from mplayer.c
894 --------------------------------------------------------------------------*/
895 /*****************************************************************
896 * \brief public wrapper for get_frequency
897 * \parameter frequency pointer to float, which will contain frequency in MHz
898 * \return 1 if success,0 - otherwise
900 int radio_get_freq(struct stream_st
*stream
, float* frequency
){
901 radio_priv_t
* priv
=(radio_priv_t
*)stream
->priv
;
905 if (get_frequency(priv
,frequency
)!=STREAM_OK
){
910 /*****************************************************************
911 * \brief public wrapper for set_frequency
912 * \parameter frequency frequency in MHz
913 * \return 1 if success,0 - otherwise
915 int radio_set_freq(struct stream_st
*stream
, float frequency
){
916 radio_priv_t
* priv
=(radio_priv_t
*)stream
->priv
;
918 if (set_frequency(priv
,frequency
)!=STREAM_OK
){
921 if (get_frequency(priv
,&frequency
)!=STREAM_OK
){
924 mp_msg(MSGT_RADIO
, MSGL_INFO
, MSGTR_RADIO_CurrentFreq
,frequency
);
928 /*****************************************************************
929 * \brief tune current frequency by step_interval value
930 * \parameter step_interval increment value
931 * \return 1 if success,0 - otherwise
934 int radio_step_freq(struct stream_st
*stream
, float step_interval
){
936 radio_priv_t
* priv
=(radio_priv_t
*)stream
->priv
;
938 if (get_frequency(priv
,&frequency
)!=STREAM_OK
)
941 frequency
+=step_interval
;
942 if (frequency
>priv
->rangehigh
)
943 frequency
=priv
->rangehigh
;
944 if (frequency
<priv
->rangelow
)
945 frequency
=priv
->rangelow
;
947 return radio_set_freq(stream
,frequency
);
949 /*****************************************************************
950 * \brief step channel up or down
951 * \parameter direction RADIO_CHANNEL_LOWER - go to prev channel,RADIO_CHANNEL_HIGHER - to next
952 * \return 1 if success,0 - otherwise
954 * if channel parameter is NULL function prints error message and does nothing, otherwise
955 * changes channel to prev or next in list
957 int radio_step_channel(struct stream_st
*stream
, int direction
) {
958 radio_priv_t
* priv
=(radio_priv_t
*)stream
->priv
;
960 if (priv
->radio_channel_list
) {
962 case RADIO_CHANNEL_HIGHER
:
963 if (priv
->radio_channel_current
->next
)
964 priv
->radio_channel_current
= priv
->radio_channel_current
->next
;
966 priv
->radio_channel_current
= priv
->radio_channel_list
;
967 if(!radio_set_freq(stream
,priv
->radio_channel_current
->freq
))
969 mp_msg(MSGT_RADIO
, MSGL_V
, MSGTR_RADIO_SelectedChannel
,
970 priv
->radio_channel_current
->index
, priv
->radio_channel_current
->name
,
971 priv
->radio_channel_current
->freq
);
973 case RADIO_CHANNEL_LOWER
:
974 if (priv
->radio_channel_current
->prev
)
975 priv
->radio_channel_current
= priv
->radio_channel_current
->prev
;
977 while (priv
->radio_channel_current
->next
)
978 priv
->radio_channel_current
= priv
->radio_channel_current
->next
;
979 if(!radio_set_freq(stream
,priv
->radio_channel_current
->freq
))
981 mp_msg(MSGT_RADIO
, MSGL_V
, MSGTR_RADIO_SelectedChannel
,
982 priv
->radio_channel_current
->index
, priv
->radio_channel_current
->name
,
983 priv
->radio_channel_current
->freq
);
987 mp_msg(MSGT_RADIO
, MSGL_ERR
, MSGTR_RADIO_ChangeChannelNoChannelList
);
991 /*****************************************************************
992 * \brief change channel to one with given index
993 * \parameter channel string, containing channel number
994 * \return 1 if success,0 - otherwise
996 * if channel parameter is NULL function prints error message and does nothing, otherwise
997 * changes channel to given
999 int radio_set_channel(struct stream_st
*stream
, char *channel
) {
1000 radio_priv_t
* priv
=(radio_priv_t
*)stream
->priv
;
1002 radio_channels_t
* tmp
;
1006 mp_msg(MSGT_RADIO
,MSGL_ERR
,MSGTR_RADIO_WrongChannelName
,channel
);
1008 if (priv
->radio_channel_list
) {
1009 channel_int
= strtol(channel
,&endptr
,10);
1010 tmp
= priv
->radio_channel_list
;
1012 //channel is not a number, so it contains channel name
1013 for ( ; tmp
; tmp
=tmp
->next
)
1014 if (!strncmp(channel
,tmp
->name
,sizeof(tmp
->name
)-1))
1017 mp_msg(MSGT_RADIO
,MSGL_ERR
,MSGTR_RADIO_WrongChannelName
,channel
);
1021 for (i
= 1; i
< channel_int
; i
++)
1026 if (tmp
->index
!=channel_int
){
1027 mp_msg(MSGT_RADIO
,MSGL_ERR
,MSGTR_RADIO_WrongChannelNumberInt
,channel_int
);
1031 priv
->radio_channel_current
=tmp
;
1032 mp_msg(MSGT_RADIO
, MSGL_V
, MSGTR_RADIO_SelectedChannel
, priv
->radio_channel_current
->index
,
1033 priv
->radio_channel_current
->name
, priv
->radio_channel_current
->freq
);
1034 if(!radio_set_freq(stream
, priv
->radio_channel_current
->freq
))
1037 mp_msg(MSGT_RADIO
, MSGL_ERR
, MSGTR_RADIO_ChangeChannelNoChannelList
);
1041 /*****************************************************************
1042 * \brief get current channel's name
1043 * \return pointer to string, containing current channel's name
1045 * NOTE: return value may be NULL (e.g. when channel list not initialized)
1047 char* radio_get_channel_name(struct stream_st
*stream
){
1048 radio_priv_t
* priv
=(radio_priv_t
*)stream
->priv
;
1049 if (priv
->radio_channel_current
) {
1050 return priv
->radio_channel_current
->name
;
1055 /*****************************************************************
1056 * \brief fills given buffer with audio data
1057 * \return number of bytes, written into buffer
1059 static int fill_buffer_s(struct stream_st
*s
, char* buffer
, int max_len
){
1062 #ifdef USE_RADIO_CAPTURE
1063 radio_priv_t
* priv
=(radio_priv_t
*)s
->priv
;
1065 if (priv
->do_capture
){
1066 len
=grab_audio_frame(priv
, buffer
,max_len
);
1070 memset(buffer
,0,len
);
1076 order if significant!
1077 when no driver explicitly specified first available will be used
1079 static const radio_driver_t
* radio_drivers
[]={
1080 #ifdef HAVE_RADIO_BSDBT848
1081 &radio_driver_bsdbt848
,
1083 #ifdef HAVE_RADIO_V4L2
1086 #ifdef HAVE_RADIO_V4L
1092 /*****************************************************************
1093 * Stream initialization
1094 * \return STREAM_OK if success, STREAM_ERROR otherwise
1096 static int open_s(stream_t
*stream
,int mode
, void* opts
, int* file_format
) {
1101 if (strncmp("radio://",stream
->url
,8) != 0)
1102 return STREAM_UNSUPPORTED
;
1104 if(mode
!= STREAM_READ
)
1105 return STREAM_UNSUPPORTED
;
1107 priv
=calloc(1,sizeof(radio_priv_t
));
1110 return STREAM_ERROR
;
1113 priv
->radio_param
=opts
;
1115 #ifdef USE_RADIO_CAPTURE
1116 if (priv
->radio_param
->capture
&& strncmp("capture",priv
->radio_param
->capture
,7)==0)
1124 if (strncmp(priv
->radio_param
->driver
,"default",7)==0)
1125 priv
->driver
=radio_drivers
[0];
1129 mp_msg(MSGT_RADIO
,MSGL_V
,MSGTR_RADIO_AvailableDrivers
);
1130 for(i
=0;radio_drivers
[i
];i
++){
1131 mp_msg(MSGT_RADIO
,MSGL_V
,"%s, ",radio_drivers
[i
]->name
);
1132 if(strcmp(priv
->radio_param
->driver
,radio_drivers
[i
]->name
)==0)
1133 priv
->driver
=radio_drivers
[i
];
1135 mp_msg(MSGT_RADIO
,MSGL_V
,"\n");
1138 mp_msg(MSGT_RADIO
, MSGL_INFO
, priv
->driver
->info
);
1140 mp_msg(MSGT_RADIO
, MSGL_INFO
, MSGTR_RADIO_DriverUnknownStr
,priv
->radio_param
->driver
);
1142 return STREAM_ERROR
;
1145 stream
->type
= STREAMTYPE_RADIO
;
1146 /* using rawaudio demuxer */
1147 *file_format
= DEMUXER_TYPE_RAWAUDIO
;
1148 stream
->flags
= STREAM_READ
;
1152 stream
->start_pos
=0;
1155 stream
->close
=close_s
;
1156 stream
->fill_buffer
=fill_buffer_s
;
1158 priv
->radio_fd
= open(priv
->radio_param
->device
, O_RDONLY
);
1159 if (priv
->radio_fd
< 0) {
1160 mp_msg(MSGT_RADIO
, MSGL_ERR
, MSGTR_RADIO_UnableOpenDevice
,
1161 priv
->radio_param
->device
, strerror(errno
));
1163 return STREAM_ERROR
;
1165 mp_msg(MSGT_RADIO
, MSGL_V
, MSGTR_RADIO_RadioDevice
, priv
->radio_fd
,priv
->radio_param
->device
);
1166 fcntl(priv
->radio_fd
, F_SETFD
, FD_CLOEXEC
);
1168 get_volume(priv
, &priv
->old_snd_volume
);
1171 if (init_frac(priv
)!=STREAM_OK
){
1173 return STREAM_ERROR
;
1176 if (parse_channels(priv
,priv
->radio_param
->freq_channel
,&frequency
)!=STREAM_OK
){
1178 return STREAM_ERROR
;
1181 if ((frequency
<priv
->rangelow
)||(frequency
>priv
->rangehigh
)){
1182 mp_msg(MSGT_RADIO
, MSGL_ERR
, MSGTR_RADIO_WrongFreq
,frequency
);
1184 return STREAM_ERROR
;
1186 mp_msg(MSGT_RADIO
, MSGL_INFO
, MSGTR_RADIO_UsingFreq
,frequency
);
1188 if(set_frequency(priv
,frequency
)!=STREAM_OK
){
1190 return STREAM_ERROR
;
1194 if (init_audio(priv
)!=STREAM_OK
){
1196 return STREAM_ERROR
;
1199 #if defined(USE_RADIO_CAPTURE) && defined(USE_STREAM_CACHE)
1200 if(priv
->do_capture
){
1202 if(!stream_enable_cache(stream
,5*priv
->audio_in
.samplerate
*priv
->audio_in
.channels
*
1203 priv
->audio_in
.bytes_per_sample
,2*priv
->audio_in
.samplerate
*priv
->audio_in
.channels
*
1204 priv
->audio_in
.bytes_per_sample
,priv
->audio_in
.blocksize
)) {
1205 mp_msg(MSGT_RADIO
, MSGL_ERR
, MSGTR_RADIO_StreamEnableCacheFailed
,strerror(errno
));
1207 return STREAM_ERROR
;
1212 set_volume(priv
,priv
->radio_param
->volume
);
1217 /*****************************************************************
1218 * Close stream. Clear structures.
1220 static void close_s(struct stream_st
* stream
){
1221 radio_priv_t
* priv
=(radio_priv_t
*)stream
->priv
;
1222 radio_channels_t
* tmp
;
1225 #ifdef USE_RADIO_CAPTURE
1226 if(priv
->audio_ringbuffer
){
1227 free(priv
->audio_ringbuffer
);
1228 priv
->audio_ringbuffer
=NULL
;
1234 while (priv
->radio_channel_list
) {
1235 tmp
=priv
->radio_channel_list
;
1236 priv
->radio_channel_list
=priv
->radio_channel_list
->next
;
1239 priv
->radio_channel_current
=NULL
;
1240 priv
->radio_channel_list
=NULL
;
1242 if (priv
->radio_fd
>0){
1243 set_volume(priv
, priv
->old_snd_volume
);
1244 close(priv
->radio_fd
);
1247 if(priv
->radio_param
)
1248 m_struct_free(&stream_opts
,priv
->radio_param
);
1253 stream_info_t stream_info_radio
= {
1256 "Vladimir Voroshilov",
1261 1 // Urls are an option string