diff options
Diffstat (limited to 'kradio3/plugins/v4lradio')
-rw-r--r-- | kradio3/plugins/v4lradio/Makefile.am | 18 | ||||
-rw-r--r-- | kradio3/plugins/v4lradio/linux/videodev.h | 432 | ||||
-rw-r--r-- | kradio3/plugins/v4lradio/linux/videodev2.h | 940 | ||||
-rw-r--r-- | kradio3/plugins/v4lradio/po/Makefile.am | 3 | ||||
-rw-r--r-- | kradio3/plugins/v4lradio/po/de.po | 362 | ||||
-rw-r--r-- | kradio3/plugins/v4lradio/po/ru.po | 362 | ||||
-rw-r--r-- | kradio3/plugins/v4lradio/v4lcfg_interfaces.cpp | 193 | ||||
-rw-r--r-- | kradio3/plugins/v4lradio/v4lcfg_interfaces.h | 151 | ||||
-rw-r--r-- | kradio3/plugins/v4lradio/v4lradio-configuration-ui.ui | 966 | ||||
-rw-r--r-- | kradio3/plugins/v4lradio/v4lradio-configuration.cpp | 648 | ||||
-rw-r--r-- | kradio3/plugins/v4lradio/v4lradio-configuration.h | 147 | ||||
-rw-r--r-- | kradio3/plugins/v4lradio/v4lradio.cpp | 1621 | ||||
-rw-r--r-- | kradio3/plugins/v4lradio/v4lradio.h | 265 |
13 files changed, 6108 insertions, 0 deletions
diff --git a/kradio3/plugins/v4lradio/Makefile.am b/kradio3/plugins/v4lradio/Makefile.am new file mode 100644 index 0000000..093d346 --- /dev/null +++ b/kradio3/plugins/v4lradio/Makefile.am @@ -0,0 +1,18 @@ +SUBDIRS = po . + +INCLUDES = $(all_includes) +METASOURCES = AUTO + +libkradio_LTLIBRARIES = libv4lradio.la +libv4lradio_la_SOURCES = v4lcfg_interfaces.cpp v4lradio-configuration.cpp \ + v4lradio-configuration-ui.ui v4lradio.cpp +libv4lradio_la_LDFLAGS = -module -avoid-version $(KDE_RPATH) $(all_libraries) + +noinst_HEADERS = v4lcfg_interfaces.h v4lradio-configuration.h v4lradio.h + +#messages: rc.cpp +# $(XGETTEXT) *.cpp *.h -o po/kradio-v4lradio.pot + +messages: rc.cpp + $(EXTRACTRC) *.rc *.ui >> rc.cpp + $(XGETTEXT) rc.cpp *.h *.cpp -o po/kradio-v4lradio.pot diff --git a/kradio3/plugins/v4lradio/linux/videodev.h b/kradio3/plugins/v4lradio/linux/videodev.h new file mode 100644 index 0000000..e16a8a8 --- /dev/null +++ b/kradio3/plugins/v4lradio/linux/videodev.h @@ -0,0 +1,432 @@ +#ifndef __LINUX_VIDEODEV_H +#define __LINUX_VIDEODEV_H + +#include <linux/types.h> +#include <linux/version.h> +//#include <linux/device.h> + +//#define HAVE_V4L2 1 +//#include <linux/videodev2.h> + +#ifdef __KERNEL__ + +#include <linux/poll.h> +#include <linux/mm.h> + +struct video_device +{ + /* device info */ + struct device *dev; + char name[32]; + int type; /* v4l1 */ + int type2; /* v4l2 */ + int hardware; + int minor; + + /* device ops + callbacks */ + struct file_operations *fops; + void (*release)(struct video_device *vfd); + + +#if 1 /* to be removed in 2.7.x */ + /* obsolete -- fops->owner is used instead */ + struct module *owner; + /* dev->driver_data will be used instead some day. + * Use the video_{get|set}_drvdata() helper functions, + * so the switch over will be transparent for you. + * Or use {pci|usb}_{get|set}_drvdata() directly. */ + void *priv; +#endif + + /* for videodev.c intenal usage -- please don't touch */ + int users; /* video_exclusive_{open|close} ... */ + struct semaphore lock; /* ... helper function uses these */ + char devfs_name[64]; /* devfs */ + struct class_device class_dev; /* sysfs */ +}; + +#define VIDEO_MAJOR 81 + +#define VFL_TYPE_GRABBER 0 +#define VFL_TYPE_VBI 1 +#define VFL_TYPE_RADIO 2 +#define VFL_TYPE_VTX 3 + +extern int video_register_device(struct video_device *, int type, int nr); +extern void video_unregister_device(struct video_device *); +extern struct video_device* video_devdata(struct file*); + +#define to_video_device(cd) container_of(cd, struct video_device, class_dev) +static inline void +video_device_create_file(struct video_device *vfd, + struct class_device_attribute *attr) +{ + class_device_create_file(&vfd->class_dev, attr); +} + +/* helper functions to alloc / release struct video_device, the + later can be used for video_device->release() */ +struct video_device *video_device_alloc(void); +void video_device_release(struct video_device *vfd); + +/* helper functions to access driver private data. */ +static inline void *video_get_drvdata(struct video_device *dev) +{ + return dev->priv; +} + +static inline void video_set_drvdata(struct video_device *dev, void *data) +{ + dev->priv = data; +} + +extern int video_exclusive_open(struct inode *inode, struct file *file); +extern int video_exclusive_release(struct inode *inode, struct file *file); +extern int video_usercopy(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg, + int (*func)(struct inode *inode, struct file *file, + unsigned int cmd, void *arg)); +#endif /* __KERNEL__ */ + +#define VID_TYPE_CAPTURE 1 /* Can capture */ +#define VID_TYPE_TUNER 2 /* Can tune */ +#define VID_TYPE_TELETEXT 4 /* Does teletext */ +#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */ +#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */ +#define VID_TYPE_CLIPPING 32 /* Can clip */ +#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */ +#define VID_TYPE_SCALES 128 /* Scalable */ +#define VID_TYPE_MONOCHROME 256 /* Monochrome only */ +#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */ +#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */ +#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */ +#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */ +#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */ + +struct video_capability +{ + char name[32]; + int type; + int channels; /* Num channels */ + int audios; /* Num audio devices */ + int maxwidth; /* Supported width */ + int maxheight; /* And height */ + int minwidth; /* Supported width */ + int minheight; /* And height */ +}; + + +struct video_channel +{ + int channel; + char name[32]; + int tuners; + __u32 flags; +#define VIDEO_VC_TUNER 1 /* Channel has a tuner */ +#define VIDEO_VC_AUDIO 2 /* Channel has audio */ + __u16 type; +#define VIDEO_TYPE_TV 1 +#define VIDEO_TYPE_CAMERA 2 + __u16 norm; /* Norm set by channel */ +}; + +struct video_tuner +{ + int tuner; + char name[32]; + unsigned long rangelow, rangehigh; /* Tuner range */ + __u32 flags; +#define VIDEO_TUNER_PAL 1 +#define VIDEO_TUNER_NTSC 2 +#define VIDEO_TUNER_SECAM 4 +#define VIDEO_TUNER_LOW 8 /* Uses KHz not MHz */ +#define VIDEO_TUNER_NORM 16 /* Tuner can set norm */ +#define VIDEO_TUNER_STEREO_ON 128 /* Tuner is seeing stereo */ +#define VIDEO_TUNER_RDS_ON 256 /* Tuner is seeing an RDS datastream */ +#define VIDEO_TUNER_MBS_ON 512 /* Tuner is seeing an MBS datastream */ + __u16 mode; /* PAL/NTSC/SECAM/OTHER */ +#define VIDEO_MODE_PAL 0 +#define VIDEO_MODE_NTSC 1 +#define VIDEO_MODE_SECAM 2 +#define VIDEO_MODE_AUTO 3 + __u16 signal; /* Signal strength 16bit scale */ +}; + +struct video_picture +{ + __u16 brightness; + __u16 hue; + __u16 colour; + __u16 contrast; + __u16 whiteness; /* Black and white only */ + __u16 depth; /* Capture depth */ + __u16 palette; /* Palette in use */ +#define VIDEO_PALETTE_GREY 1 /* Linear greyscale */ +#define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */ +#define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */ +#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */ +#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */ +#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */ +#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */ +#define VIDEO_PALETTE_YUYV 8 +#define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */ +#define VIDEO_PALETTE_YUV420 10 +#define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */ +#define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */ +#define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */ +#define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */ +#define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */ +#define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */ +#define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */ +#define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */ +}; + +struct video_audio +{ + int audio; /* Audio channel */ + __u16 volume; /* If settable */ + __u16 bass, treble; + __u32 flags; +#define VIDEO_AUDIO_MUTE 1 +#define VIDEO_AUDIO_MUTABLE 2 +#define VIDEO_AUDIO_VOLUME 4 +#define VIDEO_AUDIO_BASS 8 +#define VIDEO_AUDIO_TREBLE 16 +#define VIDEO_AUDIO_BALANCE 32 + char name[16]; +#define VIDEO_SOUND_MONO 1 +#define VIDEO_SOUND_STEREO 2 +#define VIDEO_SOUND_LANG1 4 +#define VIDEO_SOUND_LANG2 8 + __u16 mode; + __u16 balance; /* Stereo balance */ + __u16 step; /* Step actual volume uses */ +}; + +struct video_clip +{ + __s32 x,y; + __s32 width, height; + struct video_clip *next; /* For user use/driver use only */ +}; + +struct video_window +{ + __u32 x,y; /* Position of window */ + __u32 width,height; /* Its size */ + __u32 chromakey; + __u32 flags; + struct video_clip *clips; /* Set only */ + int clipcount; +#define VIDEO_WINDOW_INTERLACE 1 +#define VIDEO_WINDOW_CHROMAKEY 16 /* Overlay by chromakey */ +#define VIDEO_CLIP_BITMAP -1 +/* bitmap is 1024x625, a '1' bit represents a clipped pixel */ +#define VIDEO_CLIPMAP_SIZE (128 * 625) +}; + +struct video_capture +{ + __u32 x,y; /* Offsets into image */ + __u32 width, height; /* Area to capture */ + __u16 decimation; /* Decimation divider */ + __u16 flags; /* Flags for capture */ +#define VIDEO_CAPTURE_ODD 0 /* Temporal */ +#define VIDEO_CAPTURE_EVEN 1 +}; + +struct video_buffer +{ + void *base; + int height,width; + int depth; + int bytesperline; +}; + +struct video_mmap +{ + unsigned int frame; /* Frame (0 - n) for double buffer */ + int height,width; + unsigned int format; /* should be VIDEO_PALETTE_* */ +}; + +struct video_key +{ + __u8 key[8]; + __u32 flags; +}; + + +#define VIDEO_MAX_FRAME 32 + +struct video_mbuf +{ + int size; /* Total memory to map */ + int frames; /* Frames */ + int offsets[VIDEO_MAX_FRAME]; +}; + + +#define VIDEO_NO_UNIT (-1) + + +struct video_unit +{ + int video; /* Video minor */ + int vbi; /* VBI minor */ + int radio; /* Radio minor */ + int audio; /* Audio minor */ + int teletext; /* Teletext minor */ +}; + +struct vbi_format { + __u32 sampling_rate; /* in Hz */ + __u32 samples_per_line; + __u32 sample_format; /* VIDEO_PALETTE_RAW only (1 byte) */ + __s32 start[2]; /* starting line for each frame */ + __u32 count[2]; /* count of lines for each frame */ + __u32 flags; +#define VBI_UNSYNC 1 /* can distingues between top/bottom field */ +#define VBI_INTERLACED 2 /* lines are interlaced */ +}; + +/* video_info is biased towards hardware mpeg encode/decode */ +/* but it could apply generically to any hardware compressor/decompressor */ +struct video_info +{ + __u32 frame_count; /* frames output since decode/encode began */ + __u32 h_size; /* current unscaled horizontal size */ + __u32 v_size; /* current unscaled veritcal size */ + __u32 smpte_timecode; /* current SMPTE timecode (for current GOP) */ + __u32 picture_type; /* current picture type */ + __u32 temporal_reference; /* current temporal reference */ + __u8 user_data[256]; /* user data last found in compressed stream */ + /* user_data[0] contains user data flags, user_data[1] has count */ +}; + +/* generic structure for setting playback modes */ +struct video_play_mode +{ + int mode; + int p1; + int p2; +}; + +/* for loading microcode / fpga programming */ +struct video_code +{ + char loadwhat[16]; /* name or tag of file being passed */ + int datasize; + __u8 *data; +}; + +#define VIDIOCGCAP _IOR('v',1,struct video_capability) /* Get capabilities */ +#define VIDIOCGCHAN _IOWR('v',2,struct video_channel) /* Get channel info (sources) */ +#define VIDIOCSCHAN _IOW('v',3,struct video_channel) /* Set channel */ +#define VIDIOCGTUNER _IOWR('v',4,struct video_tuner) /* Get tuner abilities */ +#define VIDIOCSTUNER _IOW('v',5,struct video_tuner) /* Tune the tuner for the current channel */ +#define VIDIOCGPICT _IOR('v',6,struct video_picture) /* Get picture properties */ +#define VIDIOCSPICT _IOW('v',7,struct video_picture) /* Set picture properties */ +#define VIDIOCCAPTURE _IOW('v',8,int) /* Start, end capture */ +#define VIDIOCGWIN _IOR('v',9, struct video_window) /* Get the video overlay window */ +#define VIDIOCSWIN _IOW('v',10, struct video_window) /* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */ +#define VIDIOCGFBUF _IOR('v',11, struct video_buffer) /* Get frame buffer */ +#define VIDIOCSFBUF _IOW('v',12, struct video_buffer) /* Set frame buffer - root only */ +#define VIDIOCKEY _IOR('v',13, struct video_key) /* Video key event - to dev 255 is to all - cuts capture on all DMA windows with this key (0xFFFFFFFF == all) */ +#define VIDIOCGFREQ _IOR('v',14, unsigned long) /* Set tuner */ +#define VIDIOCSFREQ _IOW('v',15, unsigned long) /* Set tuner */ +#define VIDIOCGAUDIO _IOR('v',16, struct video_audio) /* Get audio info */ +#define VIDIOCSAUDIO _IOW('v',17, struct video_audio) /* Audio source, mute etc */ +#define VIDIOCSYNC _IOW('v',18, int) /* Sync with mmap grabbing */ +#define VIDIOCMCAPTURE _IOW('v',19, struct video_mmap) /* Grab frames */ +#define VIDIOCGMBUF _IOR('v',20, struct video_mbuf) /* Memory map buffer info */ +#define VIDIOCGUNIT _IOR('v',21, struct video_unit) /* Get attached units */ +#define VIDIOCGCAPTURE _IOR('v',22, struct video_capture) /* Get subcapture */ +#define VIDIOCSCAPTURE _IOW('v',23, struct video_capture) /* Set subcapture */ +#define VIDIOCSPLAYMODE _IOW('v',24, struct video_play_mode) /* Set output video mode/feature */ +#define VIDIOCSWRITEMODE _IOW('v',25, int) /* Set write mode */ +#define VIDIOCGPLAYINFO _IOR('v',26, struct video_info) /* Get current playback info from hardware */ +#define VIDIOCSMICROCODE _IOW('v',27, struct video_code) /* Load microcode into hardware */ +#define VIDIOCGVBIFMT _IOR('v',28, struct vbi_format) /* Get VBI information */ +#define VIDIOCSVBIFMT _IOW('v',29, struct vbi_format) /* Set VBI information */ + + +#define BASE_VIDIOCPRIVATE 192 /* 192-255 are private */ + +/* VIDIOCSWRITEMODE */ +#define VID_WRITE_MPEG_AUD 0 +#define VID_WRITE_MPEG_VID 1 +#define VID_WRITE_OSD 2 +#define VID_WRITE_TTX 3 +#define VID_WRITE_CC 4 +#define VID_WRITE_MJPEG 5 + +/* VIDIOCSPLAYMODE */ +#define VID_PLAY_VID_OUT_MODE 0 + /* p1: = VIDEO_MODE_PAL, VIDEO_MODE_NTSC, etc ... */ +#define VID_PLAY_GENLOCK 1 + /* p1: 0 = OFF, 1 = ON */ + /* p2: GENLOCK FINE DELAY value */ +#define VID_PLAY_NORMAL 2 +#define VID_PLAY_PAUSE 3 +#define VID_PLAY_SINGLE_FRAME 4 +#define VID_PLAY_FAST_FORWARD 5 +#define VID_PLAY_SLOW_MOTION 6 +#define VID_PLAY_IMMEDIATE_NORMAL 7 +#define VID_PLAY_SWITCH_CHANNELS 8 +#define VID_PLAY_FREEZE_FRAME 9 +#define VID_PLAY_STILL_MODE 10 +#define VID_PLAY_MASTER_MODE 11 + /* p1: see below */ +#define VID_PLAY_MASTER_NONE 1 +#define VID_PLAY_MASTER_VIDEO 2 +#define VID_PLAY_MASTER_AUDIO 3 +#define VID_PLAY_ACTIVE_SCANLINES 12 + /* p1 = first active; p2 = last active */ +#define VID_PLAY_RESET 13 +#define VID_PLAY_END_MARK 14 + + + +#define VID_HARDWARE_BT848 1 +#define VID_HARDWARE_QCAM_BW 2 +#define VID_HARDWARE_PMS 3 +#define VID_HARDWARE_QCAM_C 4 +#define VID_HARDWARE_PSEUDO 5 +#define VID_HARDWARE_SAA5249 6 +#define VID_HARDWARE_AZTECH 7 +#define VID_HARDWARE_SF16MI 8 +#define VID_HARDWARE_RTRACK 9 +#define VID_HARDWARE_ZOLTRIX 10 +#define VID_HARDWARE_SAA7146 11 +#define VID_HARDWARE_VIDEUM 12 /* Reserved for Winnov videum */ +#define VID_HARDWARE_RTRACK2 13 +#define VID_HARDWARE_PERMEDIA2 14 /* Reserved for Permedia2 */ +#define VID_HARDWARE_RIVA128 15 /* Reserved for RIVA 128 */ +#define VID_HARDWARE_PLANB 16 /* PowerMac motherboard video-in */ +#define VID_HARDWARE_BROADWAY 17 /* Broadway project */ +#define VID_HARDWARE_GEMTEK 18 +#define VID_HARDWARE_TYPHOON 19 +#define VID_HARDWARE_VINO 20 /* SGI Indy Vino */ +#define VID_HARDWARE_CADET 21 /* Cadet radio */ +#define VID_HARDWARE_TRUST 22 /* Trust FM Radio */ +#define VID_HARDWARE_TERRATEC 23 /* TerraTec ActiveRadio */ +#define VID_HARDWARE_CPIA 24 +#define VID_HARDWARE_ZR36120 25 /* Zoran ZR36120/ZR36125 */ +#define VID_HARDWARE_ZR36067 26 /* Zoran ZR36067/36060 */ +#define VID_HARDWARE_OV511 27 +#define VID_HARDWARE_ZR356700 28 /* Zoran 36700 series */ +#define VID_HARDWARE_W9966 29 +#define VID_HARDWARE_SE401 30 /* SE401 USB webcams */ +#define VID_HARDWARE_PWC 31 /* Philips webcams */ +#define VID_HARDWARE_MEYE 32 /* Sony Vaio MotionEye cameras */ +#define VID_HARDWARE_CPIA2 33 +#define VID_HARDWARE_VICAM 34 +#define VID_HARDWARE_SF16FMR2 35 +#endif /* __LINUX_VIDEODEV_H */ + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff --git a/kradio3/plugins/v4lradio/linux/videodev2.h b/kradio3/plugins/v4lradio/linux/videodev2.h new file mode 100644 index 0000000..c41831a --- /dev/null +++ b/kradio3/plugins/v4lradio/linux/videodev2.h @@ -0,0 +1,940 @@ +#ifndef __LINUX_VIDEODEV2_H +#define __LINUX_VIDEODEV2_H +/* + * Video for Linux Two + * + * Header file for v4l or V4L2 drivers and applications, for + * Linux kernels 2.2.x or 2.4.x. + * + * See http://bytesex.org/v4l/ for API specs and other + * v4l2 documentation. + * + * Author: Bill Dirks <bdirks@pacbell.net> + * Justin Schoeman + * et al. + */ + +#include <asm/types.h> +#ifdef __KERNEL__ +#include <linux/time.h> /* need struct timeval */ +#endif + +/* + * M I S C E L L A N E O U S + */ + +/* Four-character-code (FOURCC) */ +#define v4l2_fourcc(a,b,c,d)\ + (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24)) + +/* + * E N U M S + */ +enum v4l2_field { + V4L2_FIELD_ANY = 0, /* driver can choose from none, + top, bottom, interlaced + depending on whatever it thinks + is approximate ... */ + V4L2_FIELD_NONE = 1, /* this device has no fields ... */ + V4L2_FIELD_TOP = 2, /* top field only */ + V4L2_FIELD_BOTTOM = 3, /* bottom field only */ + V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */ + V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one + buffer, top-bottom order */ + V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */ + V4L2_FIELD_ALTERNATE = 7 /* both fields alternating into + separate buffers */ +}; +#define V4L2_FIELD_HAS_TOP(field) \ + ((field) == V4L2_FIELD_TOP ||\ + (field) == V4L2_FIELD_INTERLACED ||\ + (field) == V4L2_FIELD_SEQ_TB ||\ + (field) == V4L2_FIELD_SEQ_BT) +#define V4L2_FIELD_HAS_BOTTOM(field) \ + ((field) == V4L2_FIELD_BOTTOM ||\ + (field) == V4L2_FIELD_INTERLACED ||\ + (field) == V4L2_FIELD_SEQ_TB ||\ + (field) == V4L2_FIELD_SEQ_BT) +#define V4L2_FIELD_HAS_BOTH(field) \ + ((field) == V4L2_FIELD_INTERLACED ||\ + (field) == V4L2_FIELD_SEQ_TB ||\ + (field) == V4L2_FIELD_SEQ_BT) + +enum v4l2_buf_type { + V4L2_BUF_TYPE_VIDEO_CAPTURE = 1, + V4L2_BUF_TYPE_VIDEO_OUTPUT = 2, + V4L2_BUF_TYPE_VIDEO_OVERLAY = 3, + V4L2_BUF_TYPE_VBI_CAPTURE = 4, + V4L2_BUF_TYPE_VBI_OUTPUT = 5, + V4L2_BUF_TYPE_PRIVATE = 0x80 +}; + +enum v4l2_ctrl_type { + V4L2_CTRL_TYPE_INTEGER = 1, + V4L2_CTRL_TYPE_BOOLEAN = 2, + V4L2_CTRL_TYPE_MENU = 3, + V4L2_CTRL_TYPE_BUTTON = 4 +}; + +enum v4l2_tuner_type { + V4L2_TUNER_RADIO = 1, + V4L2_TUNER_ANALOG_TV = 2 +}; + +enum v4l2_memory { + V4L2_MEMORY_MMAP = 1, + V4L2_MEMORY_USERPTR = 2, + V4L2_MEMORY_OVERLAY = 3 +}; + +/* see also http://vektor.theorem.ca/graphics/ycbcr/ */ +enum v4l2_colorspace { + /* ITU-R 601 -- broadcast NTSC/PAL */ + V4L2_COLORSPACE_SMPTE170M = 1, + + /* 1125-Line (US) HDTV */ + V4L2_COLORSPACE_SMPTE240M = 2, + + /* HD and modern captures. */ + V4L2_COLORSPACE_REC709 = 3, + + /* broken BT878 extents (601, luma range 16-253 instead of 16-235) */ + V4L2_COLORSPACE_BT878 = 4, + + /* These should be useful. Assume 601 extents. */ + V4L2_COLORSPACE_470_SYSTEM_M = 5, + V4L2_COLORSPACE_470_SYSTEM_BG = 6, + + /* I know there will be cameras that send this. So, this is + * unspecified chromaticities and full 0-255 on each of the + * Y'CbCr components + */ + V4L2_COLORSPACE_JPEG = 7, + + /* For RGB colourspaces, this is probably a good start. */ + V4L2_COLORSPACE_SRGB = 8 +}; + +enum v4l2_priority { + V4L2_PRIORITY_UNSET = 0, /* not initialized */ + V4L2_PRIORITY_BACKGROUND = 1, + V4L2_PRIORITY_INTERACTIVE = 2, + V4L2_PRIORITY_RECORD = 3, + V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE +}; + +struct v4l2_rect { + __s32 left; + __s32 top; + __s32 width; + __s32 height; +}; + +struct v4l2_fract { + __u32 numerator; + __u32 denominator; +}; + +/* + * D R I V E R C A P A B I L I T I E S + */ +struct v4l2_capability +{ + __u8 driver[16]; /* i.e. "bttv" */ + __u8 card[32]; /* i.e. "Hauppauge WinTV" */ + __u8 bus_info[32]; /* "PCI:" + pci_name(pci_dev) */ + __u32 version; /* should use KERNEL_VERSION() */ + __u32 capabilities; /* Device capabilities */ + __u32 reserved[4]; +}; + +/* Values for 'capabilities' field */ +#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */ +#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */ +#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */ +#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a VBI capture device */ +#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a VBI output device */ +#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */ + +#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ +#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ +#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */ + +#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */ +#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ +#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */ + +/* + * V I D E O I M A G E F O R M A T + */ + +struct v4l2_pix_format +{ + __u32 width; + __u32 height; + __u32 pixelformat; + enum v4l2_field field; + __u32 bytesperline; /* for padding, zero if unused */ + __u32 sizeimage; + enum v4l2_colorspace colorspace; + __u32 priv; /* private data, depends on pixelformat */ +}; + +/* Pixel format FOURCC depth Description */ +#define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R','G','B','1') /* 8 RGB-3-3-2 */ +#define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R','G','B','O') /* 16 RGB-5-5-5 */ +#define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R','G','B','P') /* 16 RGB-5-6-5 */ +#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R','G','B','Q') /* 16 RGB-5-5-5 BE */ +#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R','G','B','R') /* 16 RGB-5-6-5 BE */ +#define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B','G','R','3') /* 24 BGR-8-8-8 */ +#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R','G','B','3') /* 24 RGB-8-8-8 */ +#define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B','G','R','4') /* 32 BGR-8-8-8-8 */ +#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R','G','B','4') /* 32 RGB-8-8-8-8 */ +#define V4L2_PIX_FMT_GREY v4l2_fourcc('G','R','E','Y') /* 8 Greyscale */ +#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y','V','U','9') /* 9 YVU 4:1:0 */ +#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y','V','1','2') /* 12 YVU 4:2:0 */ +#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y','U','Y','V') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U','Y','V','Y') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4','2','2','P') /* 16 YVU422 planar */ +#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4','1','1','P') /* 16 YVU411 planar */ +#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y','4','1','P') /* 12 YUV 4:1:1 */ + +/* two planes -- one Y, one Cr + Cb interleaved */ +#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N','V','1','2') /* 12 Y/CbCr 4:2:0 */ +#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N','V','2','1') /* 12 Y/CrCb 4:2:0 */ + +/* The following formats are not defined in the V4L2 specification */ +#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y','U','V','9') /* 9 YUV 4:1:0 */ +#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y','U','1','2') /* 12 YUV 4:2:0 */ +#define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y','Y','U','V') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H','I','2','4') /* 8 8-bit color */ + +/* compressed formats */ +#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M','J','P','G') /* Motion-JPEG */ +#define V4L2_PIX_FMT_JPEG v4l2_fourcc('J','P','E','G') /* JFIF JPEG */ +#define V4L2_PIX_FMT_DV v4l2_fourcc('d','v','s','d') /* 1394 */ +#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M','P','E','G') /* MPEG */ + +/* Vendor-specific formats */ +#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W','N','V','A') /* Winnov hw compress */ + +/* + * F O R M A T E N U M E R A T I O N + */ +struct v4l2_fmtdesc +{ + __u32 index; /* Format number */ + enum v4l2_buf_type type; /* buffer type */ + __u32 flags; + __u8 description[32]; /* Description string */ + __u32 pixelformat; /* Format fourcc */ + __u32 reserved[4]; +}; + +#define V4L2_FMT_FLAG_COMPRESSED 0x0001 + + +/* + * T I M E C O D E + */ +struct v4l2_timecode +{ + __u32 type; + __u32 flags; + __u8 frames; + __u8 seconds; + __u8 minutes; + __u8 hours; + __u8 userbits[4]; +}; + +/* Type */ +#define V4L2_TC_TYPE_24FPS 1 +#define V4L2_TC_TYPE_25FPS 2 +#define V4L2_TC_TYPE_30FPS 3 +#define V4L2_TC_TYPE_50FPS 4 +#define V4L2_TC_TYPE_60FPS 5 + +/* Flags */ +#define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */ +#define V4L2_TC_FLAG_COLORFRAME 0x0002 +#define V4L2_TC_USERBITS_field 0x000C +#define V4L2_TC_USERBITS_USERDEFINED 0x0000 +#define V4L2_TC_USERBITS_8BITCHARS 0x0008 +/* The above is based on SMPTE timecodes */ + + +/* + * C O M P R E S S I O N P A R A M E T E R S + */ +#if 0 +/* ### generic compression settings don't work, there is too much + * ### codec-specific stuff. Maybe reuse that for MPEG codec settings + * ### later ... */ +struct v4l2_compression +{ + __u32 quality; + __u32 keyframerate; + __u32 pframerate; + __u32 reserved[5]; + +/* what we'll need for MPEG, extracted from some postings on + the v4l list (Gert Vervoort, PlasmaJohn). + +system stream: + - type: elementary stream(ES), packatised elementary stream(s) (PES) + program stream(PS), transport stream(TS) + - system bitrate + - PS packet size (DVD: 2048 bytes, VCD: 2324 bytes) + - TS video PID + - TS audio PID + - TS PCR PID + - TS system information tables (PAT, PMT, CAT, NIT and SIT) + - (MPEG-1 systems stream vs. MPEG-2 program stream (TS not supported + by MPEG-1 systems) + +audio: + - type: MPEG (+Layer I,II,III), AC-3, LPCM + - bitrate + - sampling frequency (DVD: 48 Khz, VCD: 44.1 KHz, 32 kHz) + - Trick Modes? (ff, rew) + - Copyright + - Inverse Telecine + +video: + - picturesize (SIF, 1/2 D1, 2/3 D1, D1) and PAL/NTSC norm can be set + through excisting V4L2 controls + - noise reduction, parameters encoder specific? + - MPEG video version: MPEG-1, MPEG-2 + - GOP (Group Of Pictures) definition: + - N: number of frames per GOP + - M: distance between reference (I,P) frames + - open/closed GOP + - quantiser matrix: inter Q matrix (64 bytes) and intra Q matrix (64 bytes) + - quantiser scale: linear or logarithmic + - scanning: alternate or zigzag + - bitrate mode: CBR (constant bitrate) or VBR (variable bitrate). + - target video bitrate for CBR + - target video bitrate for VBR + - maximum video bitrate for VBR - min. quantiser value for VBR + - max. quantiser value for VBR + - adaptive quantisation value + - return the number of bytes per GOP or bitrate for bitrate monitoring + +*/ +}; +#endif + +struct v4l2_jpegcompression +{ + int quality; + + int APPn; /* Number of APP segment to be written, + * must be 0..15 */ + int APP_len; /* Length of data in JPEG APPn segment */ + char APP_data[60]; /* Data in the JPEG APPn segment. */ + + int COM_len; /* Length of data in JPEG COM segment */ + char COM_data[60]; /* Data in JPEG COM segment */ + + __u32 jpeg_markers; /* Which markers should go into the JPEG + * output. Unless you exactly know what + * you do, leave them untouched. + * Inluding less markers will make the + * resulting code smaller, but there will + * be fewer aplications which can read it. + * The presence of the APP and COM marker + * is influenced by APP_len and COM_len + * ONLY, not by this property! */ + +#define V4L2_JPEG_MARKER_DHT (1<<3) /* Define Huffman Tables */ +#define V4L2_JPEG_MARKER_DQT (1<<4) /* Define Quantization Tables */ +#define V4L2_JPEG_MARKER_DRI (1<<5) /* Define Restart Interval */ +#define V4L2_JPEG_MARKER_COM (1<<6) /* Comment segment */ +#define V4L2_JPEG_MARKER_APP (1<<7) /* App segment, driver will + * allways use APP0 */ +}; + + +/* + * M E M O R Y - M A P P I N G B U F F E R S + */ +struct v4l2_requestbuffers +{ + __u32 count; + enum v4l2_buf_type type; + enum v4l2_memory memory; + __u32 reserved[2]; +}; + +struct v4l2_buffer +{ + __u32 index; + enum v4l2_buf_type type; + __u32 bytesused; + __u32 flags; + enum v4l2_field field; + struct timeval timestamp; + struct v4l2_timecode timecode; + __u32 sequence; + + /* memory location */ + enum v4l2_memory memory; + union { + __u32 offset; + unsigned long userptr; + } m; + __u32 length; + + __u32 reserved[2]; +}; + +/* Flags for 'flags' field */ +#define V4L2_BUF_FLAG_MAPPED 0x0001 /* Buffer is mapped (flag) */ +#define V4L2_BUF_FLAG_QUEUED 0x0002 /* Buffer is queued for processing */ +#define V4L2_BUF_FLAG_DONE 0x0004 /* Buffer is ready */ +#define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */ +#define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */ +#define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */ +#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */ + +/* + * O V E R L A Y P R E V I E W + */ +struct v4l2_framebuffer +{ + __u32 capability; + __u32 flags; +/* FIXME: in theory we should pass something like PCI device + memory + * region + offset instead of some physical address */ + void* base; + struct v4l2_pix_format fmt; +}; +/* Flags for the 'capability' field. Read only */ +#define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001 +#define V4L2_FBUF_CAP_CHROMAKEY 0x0002 +#define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004 +#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008 +/* Flags for the 'flags' field. */ +#define V4L2_FBUF_FLAG_PRIMARY 0x0001 +#define V4L2_FBUF_FLAG_OVERLAY 0x0002 +#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004 + +struct v4l2_clip +{ + struct v4l2_rect c; + struct v4l2_clip *next; +}; + +struct v4l2_window +{ + struct v4l2_rect w; + enum v4l2_field field; + __u32 chromakey; + struct v4l2_clip *clips; + __u32 clipcount; + void *bitmap; +}; + + +/* + * C A P T U R E P A R A M E T E R S + */ +struct v4l2_captureparm +{ + __u32 capability; /* Supported modes */ + __u32 capturemode; /* Current mode */ + struct v4l2_fract timeperframe; /* Time per frame in .1us units */ + __u32 extendedmode; /* Driver-specific extensions */ + __u32 readbuffers; /* # of buffers for read */ + __u32 reserved[4]; +}; +/* Flags for 'capability' and 'capturemode' fields */ +#define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */ +#define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */ + +struct v4l2_outputparm +{ + __u32 capability; /* Supported modes */ + __u32 outputmode; /* Current mode */ + struct v4l2_fract timeperframe; /* Time per frame in seconds */ + __u32 extendedmode; /* Driver-specific extensions */ + __u32 writebuffers; /* # of buffers for write */ + __u32 reserved[4]; +}; + +/* + * I N P U T I M A G E C R O P P I N G + */ + +struct v4l2_cropcap { + enum v4l2_buf_type type; + struct v4l2_rect bounds; + struct v4l2_rect defrect; + struct v4l2_fract pixelaspect; +}; + +struct v4l2_crop { + enum v4l2_buf_type type; + struct v4l2_rect c; +}; + +/* + * A N A L O G V I D E O S T A N D A R D + */ + +typedef unsigned long long v4l2_std_id; + +/* one bit for each */ +#define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001) +#define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002) +#define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004) +#define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008) +#define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010) +#define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020) +#define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040) +#define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080) + +#define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100) +#define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200) +#define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400) +#define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800) + +#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000) +#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000) + +#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000) +#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000) +#define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000) +#define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000) +#define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000) +#define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000) +#define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000) + +/* ATSC/HDTV */ +#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000) +#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000) + +/* some common needed stuff */ +#define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\ + V4L2_STD_PAL_B1 |\ + V4L2_STD_PAL_G) +#define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\ + V4L2_STD_PAL_D1 |\ + V4L2_STD_PAL_K) +#define V4L2_STD_PAL (V4L2_STD_PAL_BG |\ + V4L2_STD_PAL_DK |\ + V4L2_STD_PAL_H |\ + V4L2_STD_PAL_I) +#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\ + V4L2_STD_NTSC_M_JP) +#define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\ + V4L2_STD_SECAM_D |\ + V4L2_STD_SECAM_G |\ + V4L2_STD_SECAM_H |\ + V4L2_STD_SECAM_K |\ + V4L2_STD_SECAM_K1 |\ + V4L2_STD_SECAM_L) + +#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\ + V4L2_STD_PAL_60 |\ + V4L2_STD_NTSC) +#define V4L2_STD_625_50 (V4L2_STD_PAL |\ + V4L2_STD_PAL_N |\ + V4L2_STD_PAL_Nc |\ + V4L2_STD_SECAM) + +#define V4L2_STD_UNKNOWN 0 +#define V4L2_STD_ALL (V4L2_STD_525_60 |\ + V4L2_STD_625_50) + +struct v4l2_standard +{ + __u32 index; + v4l2_std_id id; + __u8 name[24]; + struct v4l2_fract frameperiod; /* Frames, not fields */ + __u32 framelines; + __u32 reserved[4]; +}; + + +/* + * V I D E O I N P U T S + */ +struct v4l2_input +{ + __u32 index; /* Which input */ + __u8 name[32]; /* Label */ + __u32 type; /* Type of input */ + __u32 audioset; /* Associated audios (bitfield) */ + __u32 tuner; /* Associated tuner */ + v4l2_std_id std; + __u32 status; + __u32 reserved[4]; +}; +/* Values for the 'type' field */ +#define V4L2_INPUT_TYPE_TUNER 1 +#define V4L2_INPUT_TYPE_CAMERA 2 + +/* field 'status' - general */ +#define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */ +#define V4L2_IN_ST_NO_SIGNAL 0x00000002 +#define V4L2_IN_ST_NO_COLOR 0x00000004 + +/* field 'status' - analog */ +#define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */ +#define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */ + +/* field 'status' - digital */ +#define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */ +#define V4L2_IN_ST_NO_EQU 0x00020000 /* No equalizer lock */ +#define V4L2_IN_ST_NO_CARRIER 0x00040000 /* Carrier recovery failed */ + +/* field 'status' - VCR and set-top box */ +#define V4L2_IN_ST_MACROVISION 0x01000000 /* Macrovision detected */ +#define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */ +#define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */ + +/* + * V I D E O O U T P U T S + */ +struct v4l2_output +{ + __u32 index; /* Which output */ + __u8 name[32]; /* Label */ + __u32 type; /* Type of output */ + __u32 audioset; /* Associated audios (bitfield) */ + __u32 modulator; /* Associated modulator */ + v4l2_std_id std; + __u32 reserved[4]; +}; +/* Values for the 'type' field */ +#define V4L2_OUTPUT_TYPE_MODULATOR 1 +#define V4L2_OUTPUT_TYPE_ANALOG 2 +#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3 + +/* + * C O N T R O L S + */ +struct v4l2_control +{ + __u32 id; + __s32 value; +}; + +/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ +struct v4l2_queryctrl +{ + __u32 id; + enum v4l2_ctrl_type type; + __u8 name[32]; /* Whatever */ + __s32 minimum; /* Note signedness */ + __s32 maximum; + __s32 step; + __s32 default_value; + __u32 flags; + __u32 reserved[2]; +}; + +/* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */ +struct v4l2_querymenu +{ + __u32 id; + __u32 index; + __u8 name[32]; /* Whatever */ + __u32 reserved; +}; + +/* Control flags */ +#define V4L2_CTRL_FLAG_DISABLED 0x0001 +#define V4L2_CTRL_FLAG_GRABBED 0x0002 + +/* Control IDs defined by V4L2 */ +#define V4L2_CID_BASE 0x00980900 +/* IDs reserved for driver specific controls */ +#define V4L2_CID_PRIVATE_BASE 0x08000000 + +#define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0) +#define V4L2_CID_CONTRAST (V4L2_CID_BASE+1) +#define V4L2_CID_SATURATION (V4L2_CID_BASE+2) +#define V4L2_CID_HUE (V4L2_CID_BASE+3) +#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5) +#define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6) +#define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7) +#define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8) +#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9) +#define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10) +#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11) +#define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12) +#define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13) +#define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14) +#define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15) +#define V4L2_CID_GAMMA (V4L2_CID_BASE+16) +#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* ? Not sure */ +#define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17) +#define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18) +#define V4L2_CID_GAIN (V4L2_CID_BASE+19) +#define V4L2_CID_HFLIP (V4L2_CID_BASE+20) +#define V4L2_CID_VFLIP (V4L2_CID_BASE+21) +#define V4L2_CID_HCENTER (V4L2_CID_BASE+22) +#define V4L2_CID_VCENTER (V4L2_CID_BASE+23) +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+24) /* last CID + 1 */ + +/* + * T U N I N G + */ +struct v4l2_tuner +{ + __u32 index; + __u8 name[32]; + enum v4l2_tuner_type type; + __u32 capability; + __u32 rangelow; + __u32 rangehigh; + __u32 rxsubchans; + __u32 audmode; + __s32 signal; + __s32 afc; + __u32 reserved[4]; +}; + +struct v4l2_modulator +{ + __u32 index; + __u8 name[32]; + __u32 capability; + __u32 rangelow; + __u32 rangehigh; + __u32 txsubchans; + __u32 reserved[4]; +}; + +/* Flags for the 'capability' field */ +#define V4L2_TUNER_CAP_LOW 0x0001 +#define V4L2_TUNER_CAP_NORM 0x0002 +#define V4L2_TUNER_CAP_STEREO 0x0010 +#define V4L2_TUNER_CAP_LANG2 0x0020 +#define V4L2_TUNER_CAP_SAP 0x0020 +#define V4L2_TUNER_CAP_LANG1 0x0040 + +/* Flags for the 'rxsubchans' field */ +#define V4L2_TUNER_SUB_MONO 0x0001 +#define V4L2_TUNER_SUB_STEREO 0x0002 +#define V4L2_TUNER_SUB_LANG2 0x0004 +#define V4L2_TUNER_SUB_SAP 0x0004 +#define V4L2_TUNER_SUB_LANG1 0x0008 + +/* Values for the 'audmode' field */ +#define V4L2_TUNER_MODE_MONO 0x0000 +#define V4L2_TUNER_MODE_STEREO 0x0001 +#define V4L2_TUNER_MODE_LANG2 0x0002 +#define V4L2_TUNER_MODE_SAP 0x0002 +#define V4L2_TUNER_MODE_LANG1 0x0003 + +struct v4l2_frequency +{ + __u32 tuner; + enum v4l2_tuner_type type; + __u32 frequency; + __u32 reserved[8]; +}; + +/* + * A U D I O + */ +struct v4l2_audio +{ + __u32 index; + __u8 name[32]; + __u32 capability; + __u32 mode; + __u32 reserved[2]; +}; +/* Flags for the 'capability' field */ +#define V4L2_AUDCAP_STEREO 0x00001 +#define V4L2_AUDCAP_AVL 0x00002 + +/* Flags for the 'mode' field */ +#define V4L2_AUDMODE_AVL 0x00001 + +struct v4l2_audioout +{ + __u32 index; + __u8 name[32]; + __u32 capability; + __u32 mode; + __u32 reserved[2]; +}; + +/* + * D A T A S E R V I C E S ( V B I ) + * + * Data services API by Michael Schimek + */ + +struct v4l2_vbi_format +{ + __u32 sampling_rate; /* in 1 Hz */ + __u32 offset; + __u32 samples_per_line; + __u32 sample_format; /* V4L2_PIX_FMT_* */ + __s32 start[2]; + __u32 count[2]; + __u32 flags; /* V4L2_VBI_* */ + __u32 reserved[2]; /* must be zero */ +}; + +/* VBI flags */ +#define V4L2_VBI_UNSYNC (1<< 0) +#define V4L2_VBI_INTERLACED (1<< 1) + + +/* + * A G G R E G A T E S T R U C T U R E S + */ + +/* Stream data format + */ +struct v4l2_format +{ + enum v4l2_buf_type type; + union + { + struct v4l2_pix_format pix; // V4L2_BUF_TYPE_VIDEO_CAPTURE + struct v4l2_window win; // V4L2_BUF_TYPE_VIDEO_OVERLAY + struct v4l2_vbi_format vbi; // V4L2_BUF_TYPE_VBI_CAPTURE + __u8 raw_data[200]; // user-defined + } fmt; +}; + + +/* Stream type-dependent parameters + */ +struct v4l2_streamparm +{ + enum v4l2_buf_type type; + union + { + struct v4l2_captureparm capture; + struct v4l2_outputparm output; + __u8 raw_data[200]; /* user-defined */ + } parm; +}; + + + +/* + * I O C T L C O D E S F O R V I D E O D E V I C E S + * + */ +#define VIDIOC_QUERYCAP _IOR ('V', 0, struct v4l2_capability) +#define VIDIOC_RESERVED _IO ('V', 1) +#define VIDIOC_ENUM_FMT _IOWR ('V', 2, struct v4l2_fmtdesc) +#define VIDIOC_G_FMT _IOWR ('V', 4, struct v4l2_format) +#define VIDIOC_S_FMT _IOWR ('V', 5, struct v4l2_format) +#if 0 +#define VIDIOC_G_COMP _IOR ('V', 6, struct v4l2_compression) +#define VIDIOC_S_COMP _IOW ('V', 7, struct v4l2_compression) +#endif +#define VIDIOC_REQBUFS _IOWR ('V', 8, struct v4l2_requestbuffers) +#define VIDIOC_QUERYBUF _IOWR ('V', 9, struct v4l2_buffer) +#define VIDIOC_G_FBUF _IOR ('V', 10, struct v4l2_framebuffer) +#define VIDIOC_S_FBUF _IOW ('V', 11, struct v4l2_framebuffer) +#define VIDIOC_OVERLAY _IOW ('V', 14, int) +#define VIDIOC_QBUF _IOWR ('V', 15, struct v4l2_buffer) +#define VIDIOC_DQBUF _IOWR ('V', 17, struct v4l2_buffer) +#define VIDIOC_STREAMON _IOW ('V', 18, int) +#define VIDIOC_STREAMOFF _IOW ('V', 19, int) +#define VIDIOC_G_PARM _IOWR ('V', 21, struct v4l2_streamparm) +#define VIDIOC_S_PARM _IOWR ('V', 22, struct v4l2_streamparm) +#define VIDIOC_G_STD _IOR ('V', 23, v4l2_std_id) +#define VIDIOC_S_STD _IOW ('V', 24, v4l2_std_id) +#define VIDIOC_ENUMSTD _IOWR ('V', 25, struct v4l2_standard) +#define VIDIOC_ENUMINPUT _IOWR ('V', 26, struct v4l2_input) +#define VIDIOC_G_CTRL _IOWR ('V', 27, struct v4l2_control) +#define VIDIOC_S_CTRL _IOWR ('V', 28, struct v4l2_control) +#define VIDIOC_G_TUNER _IOWR ('V', 29, struct v4l2_tuner) +#define VIDIOC_S_TUNER _IOW ('V', 30, struct v4l2_tuner) +#define VIDIOC_G_AUDIO _IOR ('V', 33, struct v4l2_audio) +#define VIDIOC_S_AUDIO _IOW ('V', 34, struct v4l2_audio) +#define VIDIOC_QUERYCTRL _IOWR ('V', 36, struct v4l2_queryctrl) +#define VIDIOC_QUERYMENU _IOWR ('V', 37, struct v4l2_querymenu) +#define VIDIOC_G_INPUT _IOR ('V', 38, int) +#define VIDIOC_S_INPUT _IOWR ('V', 39, int) +#define VIDIOC_G_OUTPUT _IOR ('V', 46, int) +#define VIDIOC_S_OUTPUT _IOWR ('V', 47, int) +#define VIDIOC_ENUMOUTPUT _IOWR ('V', 48, struct v4l2_output) +#define VIDIOC_G_AUDOUT _IOR ('V', 49, struct v4l2_audioout) +#define VIDIOC_S_AUDOUT _IOW ('V', 50, struct v4l2_audioout) +#define VIDIOC_G_MODULATOR _IOWR ('V', 54, struct v4l2_modulator) +#define VIDIOC_S_MODULATOR _IOW ('V', 55, struct v4l2_modulator) +#define VIDIOC_G_FREQUENCY _IOWR ('V', 56, struct v4l2_frequency) +#define VIDIOC_S_FREQUENCY _IOW ('V', 57, struct v4l2_frequency) +#define VIDIOC_CROPCAP _IOR ('V', 58, struct v4l2_cropcap) +#define VIDIOC_G_CROP _IOWR ('V', 59, struct v4l2_crop) +#define VIDIOC_S_CROP _IOW ('V', 60, struct v4l2_crop) +#define VIDIOC_G_JPEGCOMP _IOR ('V', 61, struct v4l2_jpegcompression) +#define VIDIOC_S_JPEGCOMP _IOW ('V', 62, struct v4l2_jpegcompression) +#define VIDIOC_QUERYSTD _IOR ('V', 63, v4l2_std_id) +#define VIDIOC_TRY_FMT _IOWR ('V', 64, struct v4l2_format) +#define VIDIOC_ENUMAUDIO _IOWR ('V', 65, struct v4l2_audio) +#define VIDIOC_ENUMAUDOUT _IOWR ('V', 66, struct v4l2_audioout) +#define VIDIOC_G_PRIORITY _IOR ('V', 67, enum v4l2_priority) +#define VIDIOC_S_PRIORITY _IOW ('V', 68, enum v4l2_priority) + +/* for compatibility, will go away some day */ +#define VIDIOC_OVERLAY_OLD _IOWR ('V', 14, int) +#define VIDIOC_S_PARM_OLD _IOW ('V', 22, struct v4l2_streamparm) +#define VIDIOC_S_CTRL_OLD _IOW ('V', 28, struct v4l2_control) +#define VIDIOC_G_AUDIO_OLD _IOWR ('V', 33, struct v4l2_audio) +#define VIDIOC_G_AUDOUT_OLD _IOWR ('V', 49, struct v4l2_audioout) + +#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */ + + +#ifdef __KERNEL__ +/* + * + * V 4 L 2 D R I V E R H E L P E R A P I + * + * Some commonly needed functions for drivers (v4l2-common.o module) + */ +#include <linux/fs.h> + +/* Video standard functions */ +extern unsigned int v4l2_video_std_fps(struct v4l2_standard *vs); +extern int v4l2_video_std_construct(struct v4l2_standard *vs, + int id, char *name); + +/* prority handling */ +struct v4l2_prio_state { + atomic_t prios[4]; +}; +int v4l2_prio_init(struct v4l2_prio_state *global); +int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local, + enum v4l2_priority new); +int v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local); +int v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority *local); +enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global); +int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority *local); + +/* names for fancy debug output */ +extern char *v4l2_field_names[]; +extern char *v4l2_type_names[]; +extern char *v4l2_ioctl_names[]; + +/* Compatibility layer interface -- v4l1-compat module */ +typedef int (*v4l2_kioctl)(struct inode *inode, struct file *file, + unsigned int cmd, void *arg); +int v4l_compat_translate_ioctl(struct inode *inode, struct file *file, + int cmd, void *arg, v4l2_kioctl driver_ioctl); + +#endif /* __KERNEL__ */ +#endif /* __LINUX_VIDEODEV2_H */ + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ diff --git a/kradio3/plugins/v4lradio/po/Makefile.am b/kradio3/plugins/v4lradio/po/Makefile.am new file mode 100644 index 0000000..6f04af2 --- /dev/null +++ b/kradio3/plugins/v4lradio/po/Makefile.am @@ -0,0 +1,3 @@ + +PACKAGE = kradio-v4lradio +POFILES = AUTO diff --git a/kradio3/plugins/v4lradio/po/de.po b/kradio3/plugins/v4lradio/po/de.po new file mode 100644 index 0000000..718cb19 --- /dev/null +++ b/kradio3/plugins/v4lradio/po/de.po @@ -0,0 +1,362 @@ +# translation of de.po to +# translation of kradio-v4lradio.po to +# This file is put in the public domain. +# +# Ernst Martin Witte <emw@nocabal.de>, 2006. +msgid "" +msgstr "" +"Project-Id-Version: de\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2006-11-11 18:43+0100\n" +"PO-Revision-Date: 2006-11-06 00:24+0100\n" +"Last-Translator: Ernst Martin Witte <emw@nocabal.de>\n" +"Language-Team: <de@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" + +#. i18n: file v4lradio-configuration-ui.ui line 16 +#: rc.cpp:3 rc.cpp:90 v4lradio-configuration-ui.cpp:328 +#, no-c-format +msgid "SetupDialogGeneral" +msgstr "SetupDialogGeneral" + +#. i18n: file v4lradio-configuration-ui.ui line 37 +#: rc.cpp:6 rc.cpp:93 v4lradio-configuration-ui.cpp:344 +#, no-c-format +msgid "Devices" +msgstr "Geräte" + +#. i18n: file v4lradio-configuration-ui.ui line 68 +#: rc.cpp:9 rc.cpp:96 v4lradio-configuration-ui.cpp:329 +#, no-c-format +msgid "Playback Mixer Device" +msgstr "Wiedergabe Mixer" + +#. i18n: file v4lradio-configuration-ui.ui line 76 +#: rc.cpp:12 rc.cpp:99 v4lradio-configuration-ui.cpp:330 +#, no-c-format +msgid "Playback Mixer Channel" +msgstr "Wiedergabe Mixerkanal" + +#. i18n: file v4lradio-configuration-ui.ui line 169 +#: rc.cpp:15 rc.cpp:102 v4lradio-configuration-ui.cpp:331 +#, no-c-format +msgid "Radio Device" +msgstr "Radio Gerät" + +#. i18n: file v4lradio-configuration-ui.ui line 196 +#: rc.cpp:19 rc.cpp:106 v4lradio-configuration-ui.cpp:333 +#, no-c-format +msgid "Capture Mixer Device" +msgstr "Aufnahme Mixer" + +#. i18n: file v4lradio-configuration-ui.ui line 217 +#: rc.cpp:22 rc.cpp:109 v4lradio-configuration-ui.cpp:334 +#, no-c-format +msgid "Capture Mixer Channel" +msgstr "Aufnahme Mixerkanal" + +#. i18n: file v4lradio-configuration-ui.ui line 249 +#: rc.cpp:25 rc.cpp:112 v4lradio-configuration-ui.cpp:336 +#, no-c-format +msgid "test" +msgstr "test" + +#. i18n: file v4lradio-configuration-ui.ui line 269 +#: rc.cpp:28 rc.cpp:115 v4lradio-configuration-ui.cpp:337 +#, no-c-format +msgid "unknown v4l device" +msgstr "Unbekanntes V4L-Gerät" + +#. i18n: file v4lradio-configuration-ui.ui line 315 +#: rc.cpp:31 rc.cpp:118 v4lradio-configuration-ui.cpp:338 +#, no-c-format +msgid "Use active pla&yback by capturing" +msgstr "Aktive &Wiedergabe verwenden (Aufgenommenes abspielen)" + +#. i18n: file v4lradio-configuration-ui.ui line 318 +#: rc.cpp:34 rc.cpp:121 v4lradio-configuration-ui.cpp:339 +#, no-c-format +msgid "Alt+Y" +msgstr "Alt+Y" + +#. i18n: file v4lradio-configuration-ui.ui line 334 +#: rc.cpp:37 rc.cpp:124 v4lradio-configuration-ui.cpp:340 +#, no-c-format +msgid "Mute Play&back Channel on Power Off" +msgstr "Wiedergabekanal beim Abschalten des Radios stummschalten" + +#. i18n: file v4lradio-configuration-ui.ui line 337 +#: rc.cpp:40 rc.cpp:127 v4lradio-configuration-ui.cpp:341 +#, no-c-format +msgid "Alt+B" +msgstr "Alt+B" + +#. i18n: file v4lradio-configuration-ui.ui line 353 +#: rc.cpp:43 rc.cpp:130 v4lradio-configuration-ui.cpp:342 +#, no-c-format +msgid "Set Playback Channel Volume to &Zero on Power Off" +msgstr "Wiedergabelautstärke beim Abschalten des Radios auf 0 setzen" + +#. i18n: file v4lradio-configuration-ui.ui line 356 +#: rc.cpp:46 rc.cpp:133 v4lradio-configuration-ui.cpp:343 +#, no-c-format +msgid "Alt+Z" +msgstr "Alt+Z" + +#. i18n: file v4lradio-configuration-ui.ui line 394 +#: rc.cpp:52 rc.cpp:139 v4lradio-configuration-ui.cpp:345 +#, no-c-format +msgid "to" +msgstr "bis" + +#. i18n: file v4lradio-configuration-ui.ui line 413 +#. i18n: file v4lradio-configuration-ui.ui line 443 +#. i18n: file v4lradio-configuration-ui.ui line 479 +#. i18n: file v4lradio-configuration-ui.ui line 413 +#. i18n: file v4lradio-configuration-ui.ui line 443 +#. i18n: file v4lradio-configuration-ui.ui line 479 +#: rc.cpp:55 rc.cpp:58 rc.cpp:64 rc.cpp:142 rc.cpp:145 rc.cpp:151 +#: v4lradio-configuration-ui.cpp:346 v4lradio-configuration-ui.cpp:347 +#: v4lradio-configuration-ui.cpp:349 +#, no-c-format +msgid " kHz" +msgstr " kHz" + +#. i18n: file v4lradio-configuration-ui.ui line 460 +#: rc.cpp:61 rc.cpp:148 v4lradio-configuration-ui.cpp:348 +#, no-c-format +msgid "minimum signal quality" +msgstr "Mindest-Signalpegel" + +#. i18n: file v4lradio-configuration-ui.ui line 499 +#: rc.cpp:67 rc.cpp:154 v4lradio-configuration-ui.cpp:350 +#, no-c-format +msgid "station scan step" +msgstr "Sendersuchschrittweite" + +#. i18n: file v4lradio-configuration-ui.ui line 507 +#: rc.cpp:70 rc.cpp:157 v4lradio-configuration-ui.cpp:351 +#, no-c-format +msgid "allowed frequency range" +msgstr "erlaubter Frequenzbereich" + +#. i18n: file v4lradio-configuration-ui.ui line 566 +#: rc.cpp:75 rc.cpp:162 v4lradio-configuration-ui.cpp:359 +#, no-c-format +msgid "V4L Mixer Controls" +msgstr "V4L Mixersteuerung" + +#. i18n: file v4lradio-configuration-ui.ui line 594 +#: rc.cpp:78 rc.cpp:165 v4lradio-configuration-ui.cpp:355 +#, no-c-format +msgid "volume" +msgstr "Lautstärke" + +#. i18n: file v4lradio-configuration-ui.ui line 684 +#: rc.cpp:81 rc.cpp:168 v4lradio-configuration-ui.cpp:356 +#, no-c-format +msgid "treble" +msgstr "Höhen" + +#. i18n: file v4lradio-configuration-ui.ui line 774 +#: rc.cpp:84 rc.cpp:171 v4lradio-configuration-ui.cpp:357 +#, no-c-format +msgid "bass" +msgstr "Tiefen" + +#. i18n: file v4lradio-configuration-ui.ui line 861 +#: rc.cpp:87 rc.cpp:174 v4lradio-configuration-ui.cpp:358 +#, no-c-format +msgid "balance" +msgstr "Balance" + +#: _translatorinfo.cpp:1 +msgid "" +"_: NAME OF TRANSLATORS\n" +"Your names" +msgstr "Ernst Martin Witte" + +#: _translatorinfo.cpp:3 +msgid "" +"_: EMAIL OF TRANSLATORS\n" +"Your emails" +msgstr "emw@nocabal.de" + +#: v4lradio-configuration.cpp:443 +msgid "any ( * )" +msgstr "Alle ( * )" + +#: v4lradio-configuration.cpp:445 +msgid "Radio Device Selection" +msgstr "Auswahl der Radio-Gerätedatei" + +#: v4lradio-configuration.cpp:448 +msgid "Select Radio Device" +msgstr "Wählen Sie die Radio-Gerätedatei aus" + +#: v4lradio.cpp:56 +msgid "Support for V4L(2) Radio Devices" +msgstr "Unterstützung für V4L(2)-Radiogeräte" + +#: v4lradio.cpp:61 +msgid "Video For Linux Plugin" +msgstr "Video für Linux (V4L) Plugin" + +#: v4lradio.cpp:659 +msgid "invalid frequency %1" +msgstr "ungültige Frequenz: %1" + +#: v4lradio.cpp:680 v4lradio.cpp:1358 v4lradio.cpp:1507 +msgid "don't known how to handle V4L-version %1" +msgstr "Keine Ahnung, wie die V4L-Version %1 behandelt werden soll" + +#: v4lradio.cpp:686 +msgid "error setting frequency to %1 (%2)" +msgstr "Fehler (%2) beim Einstellen der Frequenz auf %1." + +#: v4lradio.cpp:1004 +msgid "" +"Device %1 does exist but is not readable/writable. Please check device " +"permissions." +msgstr "" +"Das Gerät %1 existiert, ist aber nicht lesbar/schreibbar. Bitte überprüfen " +"Sie die Einstellung der Zugriffsrechte für das Gerät." + +#: v4lradio.cpp:1014 +msgid "Could not find an accessible v4l(2) radio device." +msgstr "Kann kein verwendbares V4L(2)-Radiogerät finden." + +#: v4lradio.cpp:1077 +msgid "V4L Radio" +msgstr "V4L Radio" + +#: v4lradio.cpp:1078 +msgid "V4L Radio Options" +msgstr "Optionen des V4L-Radios" + +#: v4lradio.cpp:1088 +msgid "" +"V4L/V4L2 Plugin for KRadio.<P>Provides Support for V4L/V4L2 based Radio " +"Cards<P>" +msgstr "" +"V4L/V4L2-Plugin für KRadio.<P>Dieses Plugin bindet vom V4L/V4L2-Treiber " +"unterstützte Radio-Karten in KRadio ein.<P>" + +#: v4lradio.cpp:1103 +msgid "V4L/V4L2" +msgstr "V4L/V4L2" + +#: v4lradio.cpp:1104 +msgid "V4L/V4L2 Plugin" +msgstr "V4L/V4L2-Plugin" + +#: v4lradio.cpp:1135 +msgid "Cannot open radio device %1" +msgstr "Die Radiogerätedatei %1 kann nicht geöffnet werden" + +#: v4lradio.cpp:1186 +msgid "cannot open %1" +msgstr "%1 kann nicht geöffnet werden" + +#: v4lradio.cpp:1210 +msgid "audio caps = %1" +msgstr "Audio-Fähigkeiten: %1" + +#: v4lradio.cpp:1224 +msgid "error reading V4L1 caps" +msgstr "Fehler beim Lesen der V4L1-Fähigkeiten" + +#: v4lradio.cpp:1233 +msgid "V4L2 - Version: %1" +msgstr "V4L2 - Version: %1" + +#: v4lradio.cpp:1253 +msgid "V4L2: Querying mute control failed" +msgstr "V4L2: Die Abfrage des Stummschaltungs-Reglers schlug fehl" + +#: v4lradio.cpp:1260 +msgid "V4L2: Querying volume control failed" +msgstr "V4L2: Die Abfrage des Lautstärke-Reglers schlug fehl" + +#: v4lradio.cpp:1268 +msgid "V4L2: Querying treble control failed" +msgstr "V4L2: Die Abfrage des Höhen-Reglers schlug fehl" + +#: v4lradio.cpp:1276 +msgid "V4L2: Querying bass control failed" +msgstr "V4L2: Die Abfrage des Bass-Reglers schlug fehl" + +#: v4lradio.cpp:1284 +msgid "V4L2: Querying balance control failed" +msgstr "V4L2: Die Abfrage des Balance-Reglers schlug fehl" + +#: v4lradio.cpp:1288 +msgid "V4LRadio::readV4LCaps: Reading V4L2 caps failed" +msgstr "V4LRadio::readV4LCaps: Das Lesen der V4L2-Fähigkeiten schlug fehl" + +#: v4lradio.cpp:1292 +msgid "V4L %1 detected" +msgstr "V4L %1 wurde gefunden" + +#: v4lradio.cpp:1294 +msgid "V4L not detected" +msgstr "Das Radiogerät unterstützt V4L nicht" + +#: v4lradio.cpp:1297 +msgid "Radio is mutable" +msgstr "Das Radio kann stummgeschaltet werden" + +#: v4lradio.cpp:1297 +msgid "Radio is not mutable" +msgstr "Das Radio kann nicht stummgeschaltet werden" + +#: v4lradio.cpp:1298 +msgid "Radio has Volume Control" +msgstr "Das Radio hat einen Lautstärkeregler" + +#: v4lradio.cpp:1298 +msgid "Radio has no Volume Control" +msgstr "Das Radio hat keinen Lautstärkeregler" + +#: v4lradio.cpp:1299 +msgid "Radio has Bass Control" +msgstr "Das Radio hat einen Bass-Regler" + +#: v4lradio.cpp:1299 +msgid "Radio has no Bass Control" +msgstr "Das Radio hat keinen Bass-Regler" + +#: v4lradio.cpp:1300 +msgid "Radio has Treble Control" +msgstr "Das Radio hat einen Höhen-Regler" + +#: v4lradio.cpp:1300 +msgid "Radio has no Treble Control" +msgstr "Das Radio hat keinen Bass-Regler" + +#: v4lradio.cpp:1365 +msgid "cannot get tuner info (error %1)" +msgstr "Tuner-Informationen können nicht gelesen werden (Fehler %1)" + +#: v4lradio.cpp:1409 +msgid "error setting %1: %2" +msgstr "Fehler %2 beim Setzen von %1" + +#: v4lradio.cpp:1417 +msgid "error reading %1: %2" +msgstr "Fehler %2 beim Lesen von %1" + +#: v4lradio.cpp:1513 +msgid "error updating radio audio info (%1): %2" +msgstr "Fehler %2 beim Updaten der Audio-Informationen (%1)" + +#: v4lradio.cpp:1514 +msgid "write" +msgstr "Schreiben" + +#: v4lradio.cpp:1514 +msgid "read" +msgstr "Lesen" diff --git a/kradio3/plugins/v4lradio/po/ru.po b/kradio3/plugins/v4lradio/po/ru.po new file mode 100644 index 0000000..dc57522 --- /dev/null +++ b/kradio3/plugins/v4lradio/po/ru.po @@ -0,0 +1,362 @@ +# translation of ru.po to +# translation of kradio-v4lradio.po to +# This file is put in the public domain. +# Алексей Кузнецов <Alexey.Kouznetsov@GMail.com>, 2006. +# +msgid "" +msgstr "" +"Project-Id-Version: ru\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2006-11-11 18:43+0100\n" +"PO-Revision-Date: 2006-11-08 11:59+0300\n" +"Last-Translator: Алексей Кузнецов <Alexey.Kouznetsov@GMail.com>\n" +"Language-Team: <ru@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.10\n" + +#. i18n: file v4lradio-configuration-ui.ui line 16 +#: rc.cpp:3 rc.cpp:90 v4lradio-configuration-ui.cpp:328 +#, no-c-format +msgid "SetupDialogGeneral" +msgstr "SetupDialogGeneral" + +#. i18n: file v4lradio-configuration-ui.ui line 37 +#: rc.cpp:6 rc.cpp:93 v4lradio-configuration-ui.cpp:344 +#, no-c-format +msgid "Devices" +msgstr "Устройства" + +#. i18n: file v4lradio-configuration-ui.ui line 68 +#: rc.cpp:9 rc.cpp:96 v4lradio-configuration-ui.cpp:329 +#, no-c-format +msgid "Playback Mixer Device" +msgstr "Устройство воспроизведения" + +#. i18n: file v4lradio-configuration-ui.ui line 76 +#: rc.cpp:12 rc.cpp:99 v4lradio-configuration-ui.cpp:330 +#, no-c-format +msgid "Playback Mixer Channel" +msgstr "Канал воспроизведения" + +#. i18n: file v4lradio-configuration-ui.ui line 169 +#: rc.cpp:15 rc.cpp:102 v4lradio-configuration-ui.cpp:331 +#, no-c-format +msgid "Radio Device" +msgstr "Устройство радио" + +#. i18n: file v4lradio-configuration-ui.ui line 196 +#: rc.cpp:19 rc.cpp:106 v4lradio-configuration-ui.cpp:333 +#, no-c-format +msgid "Capture Mixer Device" +msgstr "Устройство записи" + +#. i18n: file v4lradio-configuration-ui.ui line 217 +#: rc.cpp:22 rc.cpp:109 v4lradio-configuration-ui.cpp:334 +#, no-c-format +msgid "Capture Mixer Channel" +msgstr "Канал записи" + +#. i18n: file v4lradio-configuration-ui.ui line 249 +#: rc.cpp:25 rc.cpp:112 v4lradio-configuration-ui.cpp:336 +#, no-c-format +msgid "test" +msgstr "проверка" + +#. i18n: file v4lradio-configuration-ui.ui line 269 +#: rc.cpp:28 rc.cpp:115 v4lradio-configuration-ui.cpp:337 +#, no-c-format +msgid "unknown v4l device" +msgstr "неизвестно" + +#. i18n: file v4lradio-configuration-ui.ui line 315 +#: rc.cpp:31 rc.cpp:118 v4lradio-configuration-ui.cpp:338 +#, no-c-format +msgid "Use active pla&yback by capturing" +msgstr "Захватывать звук и затем проигрывать его" + +#. i18n: file v4lradio-configuration-ui.ui line 318 +#: rc.cpp:34 rc.cpp:121 v4lradio-configuration-ui.cpp:339 +#, no-c-format +msgid "Alt+Y" +msgstr "Alt+Y" + +#. i18n: file v4lradio-configuration-ui.ui line 334 +#: rc.cpp:37 rc.cpp:124 v4lradio-configuration-ui.cpp:340 +#, no-c-format +msgid "Mute Play&back Channel on Power Off" +msgstr "Выключать звук на канале воспроизведения при выходе" + +#. i18n: file v4lradio-configuration-ui.ui line 337 +#: rc.cpp:40 rc.cpp:127 v4lradio-configuration-ui.cpp:341 +#, no-c-format +msgid "Alt+B" +msgstr "Alt+B" + +#. i18n: file v4lradio-configuration-ui.ui line 353 +#: rc.cpp:43 rc.cpp:130 v4lradio-configuration-ui.cpp:342 +#, no-c-format +msgid "Set Playback Channel Volume to &Zero on Power Off" +msgstr "Устанавливать &нулевую громкость воспроизведения при выходе" + +#. i18n: file v4lradio-configuration-ui.ui line 356 +#: rc.cpp:46 rc.cpp:133 v4lradio-configuration-ui.cpp:343 +#, no-c-format +msgid "Alt+Z" +msgstr "Alt+Z" + +#. i18n: file v4lradio-configuration-ui.ui line 394 +#: rc.cpp:52 rc.cpp:139 v4lradio-configuration-ui.cpp:345 +#, no-c-format +msgid "to" +msgstr "до" + +#. i18n: file v4lradio-configuration-ui.ui line 413 +#. i18n: file v4lradio-configuration-ui.ui line 443 +#. i18n: file v4lradio-configuration-ui.ui line 479 +#. i18n: file v4lradio-configuration-ui.ui line 413 +#. i18n: file v4lradio-configuration-ui.ui line 443 +#. i18n: file v4lradio-configuration-ui.ui line 479 +#: rc.cpp:55 rc.cpp:58 rc.cpp:64 rc.cpp:142 rc.cpp:145 rc.cpp:151 +#: v4lradio-configuration-ui.cpp:346 v4lradio-configuration-ui.cpp:347 +#: v4lradio-configuration-ui.cpp:349 +#, no-c-format +msgid " kHz" +msgstr " кГц" + +#. i18n: file v4lradio-configuration-ui.ui line 460 +#: rc.cpp:61 rc.cpp:148 v4lradio-configuration-ui.cpp:348 +#, no-c-format +msgid "minimum signal quality" +msgstr "Минимальный уровень сигнала" + +#. i18n: file v4lradio-configuration-ui.ui line 499 +#: rc.cpp:67 rc.cpp:154 v4lradio-configuration-ui.cpp:350 +#, no-c-format +msgid "station scan step" +msgstr "Шаг изменения частоты при поиске" + +#. i18n: file v4lradio-configuration-ui.ui line 507 +#: rc.cpp:70 rc.cpp:157 v4lradio-configuration-ui.cpp:351 +#, no-c-format +msgid "allowed frequency range" +msgstr "Допустимый частотный диапазон:\tот" + +#. i18n: file v4lradio-configuration-ui.ui line 566 +#: rc.cpp:75 rc.cpp:162 v4lradio-configuration-ui.cpp:359 +#, no-c-format +msgid "V4L Mixer Controls" +msgstr "Аппаратные регуляторы V4l" + +#. i18n: file v4lradio-configuration-ui.ui line 594 +#: rc.cpp:78 rc.cpp:165 v4lradio-configuration-ui.cpp:355 +#, no-c-format +msgid "volume" +msgstr "Громкость" + +#. i18n: file v4lradio-configuration-ui.ui line 684 +#: rc.cpp:81 rc.cpp:168 v4lradio-configuration-ui.cpp:356 +#, no-c-format +msgid "treble" +msgstr "ВЧ" + +#. i18n: file v4lradio-configuration-ui.ui line 774 +#: rc.cpp:84 rc.cpp:171 v4lradio-configuration-ui.cpp:357 +#, no-c-format +msgid "bass" +msgstr "НЧ" + +#. i18n: file v4lradio-configuration-ui.ui line 861 +#: rc.cpp:87 rc.cpp:174 v4lradio-configuration-ui.cpp:358 +#, no-c-format +msgid "balance" +msgstr "Стереобаланс" + +#: _translatorinfo.cpp:1 +msgid "" +"_: NAME OF TRANSLATORS\n" +"Your names" +msgstr "Алексей Кузнецов" + +#: _translatorinfo.cpp:3 +msgid "" +"_: EMAIL OF TRANSLATORS\n" +"Your emails" +msgstr "Alexey.Kouznetsov@GMail.com" + +#: v4lradio-configuration.cpp:443 +msgid "any ( * )" +msgstr "Все ( * )" + +#: v4lradio-configuration.cpp:445 +msgid "Radio Device Selection" +msgstr "Выбор устройства радио" + +#: v4lradio-configuration.cpp:448 +msgid "Select Radio Device" +msgstr "Выберите устройство радиоприёмника" + +#: v4lradio.cpp:56 +msgid "Support for V4L(2) Radio Devices" +msgstr "Поддержка устройств V4l(2)" + +#: v4lradio.cpp:61 +msgid "Video For Linux Plugin" +msgstr "Модуль \"Видео для linux\"" + +#: v4lradio.cpp:659 +msgid "invalid frequency %1" +msgstr "Неправильная частота %1" + +#: v4lradio.cpp:680 v4lradio.cpp:1358 v4lradio.cpp:1507 +msgid "don't known how to handle V4L-version %1" +msgstr "Не знаю что делать с версией V4l \"%1\"" + +#: v4lradio.cpp:686 +msgid "error setting frequency to %1 (%2)" +msgstr "Ошибка установки частоты %1 (%2)" + +#: v4lradio.cpp:1004 +msgid "" +"Device %1 does exist but is not readable/writable. Please check device " +"permissions." +msgstr "" +"Устройство %1 недоступно для чтения/записи. Проверьте права на устройство, а " +"также не использует ли его другая программа." + +#: v4lradio.cpp:1014 +msgid "Could not find an accessible v4l(2) radio device." +msgstr "Не найти доступное устройство V4l(2)." + +#: v4lradio.cpp:1077 +msgid "V4L Radio" +msgstr "Радио V4l" + +#: v4lradio.cpp:1078 +msgid "V4L Radio Options" +msgstr "Параметры устройства V4l" + +#: v4lradio.cpp:1088 +msgid "" +"V4L/V4L2 Plugin for KRadio.<P>Provides Support for V4L/V4L2 based Radio " +"Cards<P>" +msgstr "" +"Модуль V4l/V4l2 для KRadio. <P> Предоставляет поддержку плат радио, " +"совместимых с V4l/V4l2<P>" + +#: v4lradio.cpp:1103 +msgid "V4L/V4L2" +msgstr "V4L/V4LV2" + +#: v4lradio.cpp:1104 +msgid "V4L/V4L2 Plugin" +msgstr "Модуль V4L/V4L2" + +#: v4lradio.cpp:1135 +msgid "Cannot open radio device %1" +msgstr "Не могу открыть устройство радио: %1" + +#: v4lradio.cpp:1186 +msgid "cannot open %1" +msgstr "Не могу открыть %1" + +#: v4lradio.cpp:1210 +msgid "audio caps = %1" +msgstr "возможности звука = %1" + +#: v4lradio.cpp:1224 +msgid "error reading V4L1 caps" +msgstr "Ошибка чтения возможностей V4l1" + +#: v4lradio.cpp:1233 +msgid "V4L2 - Version: %1" +msgstr "Версия V4l2: %1" + +#: v4lradio.cpp:1253 +msgid "V4L2: Querying mute control failed" +msgstr "V4L2: Не могу обратиться к выключателю звука платы" + +#: v4lradio.cpp:1260 +msgid "V4L2: Querying volume control failed" +msgstr "V4L2: Не могу обратиться к регулятору громкости" + +#: v4lradio.cpp:1268 +msgid "V4L2: Querying treble control failed" +msgstr "V4L2: Не могу обратиться к регулятору верхних частот" + +#: v4lradio.cpp:1276 +msgid "V4L2: Querying bass control failed" +msgstr "V4L2: Не могу обратиться к регулятору нижних частот" + +#: v4lradio.cpp:1284 +msgid "V4L2: Querying balance control failed" +msgstr "V4L2: Не могу обратиться к регулятору стереобаланса" + +#: v4lradio.cpp:1288 +msgid "V4LRadio::readV4LCaps: Reading V4L2 caps failed" +msgstr "V4LRadio::readV4LCaps:Не могу узнать возможности устройства" + +#: v4lradio.cpp:1292 +msgid "V4L %1 detected" +msgstr "Найдено устройство V4L: %1" + +#: v4lradio.cpp:1294 +msgid "V4L not detected" +msgstr "Устройств V4L не обнаружено" + +#: v4lradio.cpp:1297 +msgid "Radio is mutable" +msgstr "Радио не поддерживает выключения звука" + +#: v4lradio.cpp:1297 +msgid "Radio is not mutable" +msgstr "Радио поддерживает выключение звука" + +#: v4lradio.cpp:1298 +msgid "Radio has Volume Control" +msgstr "Есть регулировка громкости" + +#: v4lradio.cpp:1298 +msgid "Radio has no Volume Control" +msgstr "Регулировки громкости нет" + +#: v4lradio.cpp:1299 +msgid "Radio has Bass Control" +msgstr "Есть регулировка НЧ" + +#: v4lradio.cpp:1299 +msgid "Radio has no Bass Control" +msgstr "Регулировки НЧ нет" + +#: v4lradio.cpp:1300 +msgid "Radio has Treble Control" +msgstr "Есть регулировка ВЧ" + +#: v4lradio.cpp:1300 +msgid "Radio has no Treble Control" +msgstr "Регулировки ВЧ нет" + +#: v4lradio.cpp:1365 +msgid "cannot get tuner info (error %1)" +msgstr "Не могу получить информацию о тюнере (код ошибки %1)" + +#: v4lradio.cpp:1409 +msgid "error setting %1: %2" +msgstr "Ошибка установки %1: %2" + +#: v4lradio.cpp:1417 +msgid "error reading %1: %2" +msgstr "Ошибка чтения %1: %2" + +#: v4lradio.cpp:1513 +msgid "error updating radio audio info (%1): %2" +msgstr "Ошибка %1: %2" + +#: v4lradio.cpp:1514 +msgid "write" +msgstr "запись" + +#: v4lradio.cpp:1514 +msgid "read" +msgstr "чтение" diff --git a/kradio3/plugins/v4lradio/v4lcfg_interfaces.cpp b/kradio3/plugins/v4lradio/v4lcfg_interfaces.cpp new file mode 100644 index 0000000..c679c76 --- /dev/null +++ b/kradio3/plugins/v4lradio/v4lcfg_interfaces.cpp @@ -0,0 +1,193 @@ +/*************************************************************************** + v4lradio_interfaces.cpp - description + ------------------- + begin : Sam Jun 21 2003 + copyright : (C) 2003 by Martin Witte + email : witte@kawo1.rwth-aachen.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include <linux/soundcard.h> +#include "v4lcfg_interfaces.h" + +/////////////////////////////////////////////////////////////////////// + +V4LCaps::V4LCaps() + : version(0), + description(QString::null), + hasMute(false), + hasVolume(false), + minVolume(0), + maxVolume(65535), + hasTreble(false), + minTreble(0), + maxTreble(65535), + hasBass(false), + minBass(0), + maxBass(65535), + hasBalance(false), + minBalance(0), + maxBalance(65535) +{ +} + + +V4LCaps::V4LCaps(const V4LCaps &c) + : version(c.version), + description(c.description), + hasMute(c.hasMute), + hasVolume(c.hasVolume), + minVolume(c.minVolume), + maxVolume(c.maxVolume), + hasTreble(c.hasTreble), + minTreble(c.minTreble), + maxTreble(c.maxTreble), + hasBass(c.hasBass), + minBass(c.minBass), + maxBass(c.maxBass), + hasBalance(c.hasBalance), + minBalance(c.minBalance), + maxBalance(c.maxBalance) +{ +} + + +// IV4LCfg + +IF_IMPL_SENDER ( IV4LCfg::notifyRadioDeviceChanged(const QString &s), + noticeRadioDeviceChanged(s) + ) +IF_IMPL_SENDER ( IV4LCfg::notifyPlaybackMixerChanged(const QString &s, const QString &Channel), + noticePlaybackMixerChanged(s, Channel) + ) +IF_IMPL_SENDER ( IV4LCfg::notifyCaptureMixerChanged(const QString &s, const QString &Channel), + noticeCaptureMixerChanged(s, Channel) + ) +IF_IMPL_SENDER ( IV4LCfg::notifyDeviceVolumeChanged(float v), + noticeDeviceVolumeChanged(v) + ) +IF_IMPL_SENDER ( IV4LCfg::notifyCapabilitiesChanged(const V4LCaps &c), + noticeCapabilitiesChanged(c) + ) + +IF_IMPL_SENDER ( IV4LCfg::notifyActivePlaybackChanged(bool a), + noticeActivePlaybackChanged(a) + ) + +IF_IMPL_SENDER ( IV4LCfg::notifyMuteOnPowerOffChanged(bool a), + noticeMuteOnPowerOffChanged(a) + ) + +IF_IMPL_SENDER ( IV4LCfg::notifyVolumeZeroOnPowerOffChanged(bool a), + noticeVolumeZeroOnPowerOffChanged(a) + ) +// IV4LCfgClient + +IF_IMPL_SENDER ( IV4LCfgClient::sendRadioDevice (const QString &s), + setRadioDevice(s) + ) +IF_IMPL_SENDER ( IV4LCfgClient::sendPlaybackMixer(const QString &s, const QString &ch), + setPlaybackMixer(s, ch) + ) +IF_IMPL_SENDER ( IV4LCfgClient::sendCaptureMixer(const QString &s, const QString &ch), + setCaptureMixer(s, ch) + ) +IF_IMPL_SENDER ( IV4LCfgClient::sendDeviceVolume(float v), + setDeviceVolume(v) + ) + +IF_IMPL_SENDER ( IV4LCfgClient::sendActivePlayback(bool a), + setActivePlayback(a) + ) + +IF_IMPL_SENDER ( IV4LCfgClient::sendMuteOnPowerOff(bool a), + setMuteOnPowerOff(a) + ) + +IF_IMPL_SENDER ( IV4LCfgClient::sendVolumeZeroOnPowerOff(bool a), + setVolumeZeroOnPowerOff(a) + ) + +static QString defaultRDev("/dev/radio"); +// static QString defaultMDev("/dev/mixer"); + +IF_IMPL_QUERY ( const QString &IV4LCfgClient::queryRadioDevice (), + getRadioDevice(), + defaultRDev + ) +IF_IMPL_QUERY ( const QString &IV4LCfgClient::queryPlaybackMixerID (), + getPlaybackMixerID(), + QString::null + ) +IF_IMPL_QUERY ( const QString &IV4LCfgClient::queryCaptureMixerID (), + getCaptureMixerID(), + QString::null + ) + +static const QString channel_line("Line"); +IF_IMPL_QUERY ( const QString &IV4LCfgClient::queryPlaybackMixerChannel(), + getPlaybackMixerChannel(), + channel_line + ) +IF_IMPL_QUERY ( const QString &IV4LCfgClient::queryCaptureMixerChannel(), + getCaptureMixerChannel(), + channel_line + ) +IF_IMPL_QUERY ( float IV4LCfgClient::queryDeviceVolume (), + getDeviceVolume(), + 0.0 + ) +IF_IMPL_QUERY ( V4LCaps IV4LCfgClient::queryCapabilities(QString dev), + getCapabilities(dev), + V4LCaps() + ) + +IF_IMPL_QUERY ( bool IV4LCfgClient::queryActivePlayback(), + getActivePlayback(), + false + ) + +IF_IMPL_QUERY ( bool IV4LCfgClient::queryMuteOnPowerOff(), + getMuteOnPowerOff(), + false + ) + +IF_IMPL_QUERY ( bool IV4LCfgClient::queryVolumeZeroOnPowerOff(), + getVolumeZeroOnPowerOff(), + false + ) + +void IV4LCfgClient::noticeConnectedI (cmplInterface *, bool /*pointer_valid*/) +{ + noticeRadioDeviceChanged(queryRadioDevice()); + noticePlaybackMixerChanged(queryPlaybackMixerID(), queryPlaybackMixerChannel()); + noticeCaptureMixerChanged (queryCaptureMixerID(), queryCaptureMixerChannel()); + noticeDeviceVolumeChanged(queryDeviceVolume()); + noticeCapabilitiesChanged(queryCapabilities()); + noticeActivePlaybackChanged(queryActivePlayback()); + noticeMuteOnPowerOffChanged(queryMuteOnPowerOff()); + noticeVolumeZeroOnPowerOffChanged(queryVolumeZeroOnPowerOff()); +} + + +void IV4LCfgClient::noticeDisconnectedI (cmplInterface *, bool /*pointer_valid*/) +{ + noticeRadioDeviceChanged(queryRadioDevice()); + noticePlaybackMixerChanged(queryPlaybackMixerID(), queryPlaybackMixerChannel()); + noticeCaptureMixerChanged (queryCaptureMixerID(), queryCaptureMixerChannel()); + noticeDeviceVolumeChanged(queryDeviceVolume()); + noticeCapabilitiesChanged(queryCapabilities()); + noticeActivePlaybackChanged(queryActivePlayback()); + noticeMuteOnPowerOffChanged(queryMuteOnPowerOff()); + noticeVolumeZeroOnPowerOffChanged(queryVolumeZeroOnPowerOff()); +} + + diff --git a/kradio3/plugins/v4lradio/v4lcfg_interfaces.h b/kradio3/plugins/v4lradio/v4lcfg_interfaces.h new file mode 100644 index 0000000..f2e1032 --- /dev/null +++ b/kradio3/plugins/v4lradio/v4lcfg_interfaces.h @@ -0,0 +1,151 @@ +/*************************************************************************** + v4lradio_interfaces.h - description + ------------------- + begin : Sam Jun 21 2003 + copyright : (C) 2003 by Martin Witte + email : witte@kawo1.rwth-aachen.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KRADIO_V4LCFG_INTERFACES_H +#define KRADIO_V4LCFG_INTERFACES_H + +#include "../../src/include/interfaces.h" +#include "math.h" + +struct V4LCaps +{ + int version; + QString description; + + bool hasMute; + + bool hasVolume; + int minVolume, maxVolume; + bool hasTreble; + int minTreble, maxTreble; + bool hasBass; + int minBass, maxBass; + bool hasBalance; + int minBalance, maxBalance; + + V4LCaps(); + V4LCaps(const V4LCaps &); + + float volumeStep() const { return 1.0 / (float)(maxVolume - minVolume); } + float trebleStep() const { return 1.0 / (float)(maxTreble - minTreble); } + float bassStep() const { return 1.0 / (float)(maxBass - minBass); } + float balanceStep() const { return 1.0 / (float)(maxBalance - minBalance); } + + void setVolume (int min, int max) { hasVolume = true; minVolume = min; maxVolume = max; } + void setTreble (int min, int max) { hasTreble = true; minTreble = min; maxTreble = max; } + void setBass (int min, int max) { hasBass = true; minBass = min; maxBass = max; } + void setBalance(int min, int max) { hasBalance = true; minBalance = min; maxBalance = max; } + + void unsetVolume () { hasVolume = false; minVolume = 0; maxVolume = 65535; } + void unsetTreble () { hasTreble = false; minTreble = 0; maxTreble = 65535; } + void unsetBass () { hasBass = false; minBass = 0; maxBass = 65535; } + void unsetBalance() { hasBalance = false; minBalance = 0; maxBalance = 65535; } + + int intGetVolume (float f) const { return (int)rint(minVolume + (maxVolume - minVolume ) * f); } + int intGetTreble (float f) const { return (int)rint(minTreble + (maxTreble - minTreble ) * f); } + int intGetBass (float f) const { return (int)rint(minBass + (maxBass - minBass ) * f); } + int intGetBalance(float f) const { return (int)rint(minBalance + (maxBalance - minBalance) / 2.0 * (1.0 + f)); } + + float floatGetVolume (int i) const { return (float)(i - minVolume) * volumeStep(); } + float floatGetTreble (int i) const { return (float)(i - minTreble) * trebleStep(); } + float floatGetBass (int i) const { return (float)(i - minBass ) * bassStep(); } + float floatGetBalance(int i) const { return (float)(i - minBalance) * balanceStep() * 2.0 - 1.0; } +}; + + + +INTERFACE(IV4LCfg, IV4LCfgClient) +{ +public: + IF_CON_DESTRUCTOR(IV4LCfg, -1) + +RECEIVERS: + IF_RECEIVER( setRadioDevice (const QString &s) ) + IF_RECEIVER( setPlaybackMixer(const QString &soundStreamClientID, const QString &ch) ) + IF_RECEIVER( setCaptureMixer (const QString &soundStreamClientID, const QString &ch) ) + IF_RECEIVER( setDeviceVolume(float v) ) + IF_RECEIVER( setActivePlayback(bool a) ) + IF_RECEIVER( setMuteOnPowerOff(bool m) ) + IF_RECEIVER( setVolumeZeroOnPowerOff(bool m) ) + +SENDERS: + IF_SENDER ( notifyRadioDeviceChanged (const QString &s) ) + IF_SENDER ( notifyPlaybackMixerChanged(const QString &soundStreamClientID, const QString &Channel) ) + IF_SENDER ( notifyCaptureMixerChanged (const QString &soundStreamClientID, const QString &Channel) ) + IF_SENDER ( notifyDeviceVolumeChanged (float v) ) + IF_SENDER ( notifyCapabilitiesChanged (const V4LCaps &) ) + IF_SENDER ( notifyActivePlaybackChanged (bool a) ) + IF_SENDER ( notifyMuteOnPowerOffChanged (bool a) ) + IF_SENDER ( notifyVolumeZeroOnPowerOffChanged (bool a) ) + +ANSWERS: + IF_ANSWER ( const QString &getRadioDevice () const ) + IF_ANSWER ( const QString &getPlaybackMixerID () const ) + IF_ANSWER ( const QString &getCaptureMixerID () const ) + IF_ANSWER ( const QString &getPlaybackMixerChannel() const ) + IF_ANSWER ( const QString &getCaptureMixerChannel() const ) + IF_ANSWER ( float getDeviceVolume() const ) + IF_ANSWER ( V4LCaps getCapabilities(QString dev = QString::null) const ) + IF_ANSWER ( bool getActivePlayback() const ) + IF_ANSWER ( bool getMuteOnPowerOff() const ) + IF_ANSWER ( bool getVolumeZeroOnPowerOff() const ) +}; + + + +INTERFACE(IV4LCfgClient, IV4LCfg) +{ +public: + IF_CON_DESTRUCTOR(IV4LCfgClient, 1) + +SENDERS: + IF_SENDER ( sendRadioDevice (const QString &s) ) + IF_SENDER ( sendPlaybackMixer(const QString &soundStreamClientID, const QString &ch) ) + IF_SENDER ( sendCaptureMixer (const QString &soundStreamClientID, const QString &ch) ) + IF_SENDER ( sendDeviceVolume(float v) ) + IF_SENDER ( sendActivePlayback(bool a) ) + IF_SENDER ( sendMuteOnPowerOff(bool a) ) + IF_SENDER ( sendVolumeZeroOnPowerOff(bool a) ) + +RECEIVERS: + IF_RECEIVER( noticeRadioDeviceChanged(const QString &s) ) + IF_RECEIVER( noticePlaybackMixerChanged(const QString &soundStreamClientID, const QString &Channel) ) + IF_RECEIVER( noticeCaptureMixerChanged (const QString &soundStreamClientID, const QString &Channel) ) + IF_RECEIVER( noticeDeviceVolumeChanged(float v) ) + IF_RECEIVER( noticeCapabilitiesChanged(const V4LCaps &) ) + IF_RECEIVER( noticeActivePlaybackChanged(bool a) ) + IF_RECEIVER( noticeMuteOnPowerOffChanged(bool a) ) + IF_RECEIVER( noticeVolumeZeroOnPowerOffChanged(bool a) ) + +QUERIES: + IF_QUERY ( const QString &queryRadioDevice () ) + IF_QUERY ( const QString &queryPlaybackMixerID () ) + IF_QUERY ( const QString &queryCaptureMixerID () ) + IF_QUERY ( const QString &queryPlaybackMixerChannel() ) + IF_QUERY ( const QString &queryCaptureMixerChannel() ) + IF_QUERY ( float queryDeviceVolume() ) + IF_QUERY ( V4LCaps queryCapabilities(QString dev = QString::null) ) + IF_QUERY ( bool queryActivePlayback() ) + IF_QUERY ( bool queryMuteOnPowerOff() ) + IF_QUERY ( bool queryVolumeZeroOnPowerOff() ) + +RECEIVERS: + virtual void noticeConnectedI (cmplInterface *, bool /*pointer_valid*/); + virtual void noticeDisconnectedI (cmplInterface *, bool /*pointer_valid*/); +}; + +#endif diff --git a/kradio3/plugins/v4lradio/v4lradio-configuration-ui.ui b/kradio3/plugins/v4lradio/v4lradio-configuration-ui.ui new file mode 100644 index 0000000..2cc4cfd --- /dev/null +++ b/kradio3/plugins/v4lradio/v4lradio-configuration-ui.ui @@ -0,0 +1,966 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>V4LRadioConfigurationUI</class> +<widget class="QWidget"> + <property name="name"> + <cstring>V4LRadioConfigurationUI</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>512</width> + <height>357</height> + </rect> + </property> + <property name="caption"> + <string>SetupDialogGeneral</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QTabWidget" row="0" column="0"> + <property name="name"> + <cstring>kTabWidget1</cstring> + </property> + <property name="currentPage"> + <number>0</number> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>TabPage</cstring> + </property> + <attribute name="title"> + <string>Devices</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <spacer row="1" column="2"> + <property name="name"> + <cstring>spacer18_3_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Preferred</enum> + </property> + <property name="sizeHint"> + <size> + <width>40</width> + <height>21</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>labelPlaybackMixerDevice</cstring> + </property> + <property name="text"> + <string>Playback Mixer Device</string> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>labelPlaybackMixerChannel</cstring> + </property> + <property name="text"> + <string>Playback Mixer Channel</string> + </property> + </widget> + <spacer row="2" column="2"> + <property name="name"> + <cstring>spacer18_3_4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Preferred</enum> + </property> + <property name="sizeHint"> + <size> + <width>40</width> + <height>21</height> + </size> + </property> + </spacer> + <spacer row="3" column="2"> + <property name="name"> + <cstring>spacer18_3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Preferred</enum> + </property> + <property name="sizeHint"> + <size> + <width>40</width> + <height>21</height> + </size> + </property> + </spacer> + <spacer row="4" column="2"> + <property name="name"> + <cstring>spacer18_3_4_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Preferred</enum> + </property> + <property name="sizeHint"> + <size> + <width>40</width> + <height>21</height> + </size> + </property> + </spacer> + <spacer row="5" column="2"> + <property name="name"> + <cstring>spacer18_3_5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Preferred</enum> + </property> + <property name="sizeHint"> + <size> + <width>40</width> + <height>21</height> + </size> + </property> + </spacer> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer18_3_3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Preferred</enum> + </property> + <property name="sizeHint"> + <size> + <width>152</width> + <height>21</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>labelRadioDevice</cstring> + </property> + <property name="text"> + <string>Radio Device</string> + </property> + </widget> + <widget class="QPushButton" row="0" column="2"> + <property name="name"> + <cstring>buttonSelectRadioDevice</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + <property name="iconSet"> + <iconset>"fileopen"</iconset> + </property> + </widget> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>labelCaptureMixerDevice</cstring> + </property> + <property name="text"> + <string>Capture Mixer Device</string> + </property> + </widget> + <widget class="QComboBox" row="5" column="1"> + <property name="name"> + <cstring>comboCaptureMixerChannel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + <widget class="QLabel" row="5" column="0"> + <property name="name"> + <cstring>labelCaptureMixerChannel</cstring> + </property> + <property name="text"> + <string>Capture Mixer Channel</string> + </property> + </widget> + <widget class="QComboBox" row="4" column="1"> + <property name="name"> + <cstring>comboCaptureMixerDevice</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + <widget class="QComboBox" row="3" column="1"> + <property name="name"> + <cstring>comboPlaybackMixerChannel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + <widget class="QComboBox" row="2" column="1"> + <item> + <property name="text"> + <string>test</string> + </property> + </item> + <property name="name"> + <cstring>comboPlaybackMixerDevice</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + <widget class="QLabel" row="1" column="1"> + <property name="name"> + <cstring>labelDescription</cstring> + </property> + <property name="text"> + <string>unknown v4l device</string> + </property> + </widget> + <widget class="QLineEdit" row="0" column="1"> + <property name="name"> + <cstring>editRadioDevice</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + <spacer row="9" column="1"> + <property name="name"> + <cstring>spacer15</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>5</width> + <height>5</height> + </size> + </property> + </spacer> + <widget class="QCheckBox" row="6" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>m_checkboxActivePlayback</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Use active pla&yback by capturing</string> + </property> + <property name="accel"> + <string>Alt+Y</string> + </property> + </widget> + <widget class="QCheckBox" row="7" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>m_checkboxMuteOnPowerOff</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Mute Play&back Channel on Power Off</string> + </property> + <property name="accel"> + <string>Alt+B</string> + </property> + </widget> + <widget class="QCheckBox" row="8" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>m_checkboxVolumeZeroOnPowerOff</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Set Playback Channel Volume to &Zero on Power Off</string> + </property> + <property name="accel"> + <string>Alt+Z</string> + </property> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>TabPage</cstring> + </property> + <attribute name="title"> + <string>Options</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <widget class="QLayoutWidget" row="0" column="2"> + <property name="name"> + <cstring>layout37</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>labelFrequencyRange</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>to</string> + </property> + </widget> + <widget class="QSpinBox"> + <property name="name"> + <cstring>editMaxFrequency</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="suffix"> + <string> kHz</string> + </property> + <property name="maxValue"> + <number>300000</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + <property name="lineStep"> + <number>1000</number> + </property> + <property name="value"> + <number>300000</number> + </property> + </widget> + </hbox> + </widget> + <widget class="QSpinBox" row="1" column="1"> + <property name="name"> + <cstring>editScanStep</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="suffix"> + <string> kHz</string> + </property> + <property name="maxValue"> + <number>500</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + <property name="value"> + <number>50</number> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>labelSignalMinQuality</cstring> + </property> + <property name="text"> + <string>minimum signal quality</string> + </property> + </widget> + <widget class="QSpinBox" row="0" column="1"> + <property name="name"> + <cstring>editMinFrequency</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="suffix"> + <string> kHz</string> + </property> + <property name="maxValue"> + <number>2999999</number> + </property> + <property name="minValue"> + <number>0</number> + </property> + <property name="lineStep"> + <number>1000</number> + </property> + <property name="value"> + <number>0</number> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>labelScanStep</cstring> + </property> + <property name="text"> + <string>station scan step</string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>labelMinMaxFrequency</cstring> + </property> + <property name="text"> + <string>allowed frequency range</string> + </property> + </widget> + <widget class="QLabel" row="1" column="2"> + <property name="name"> + <cstring>textLabel1_3</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="QSpinBox" row="2" column="1"> + <property name="name"> + <cstring>editSignalMinQuality</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="value"> + <number>75</number> + </property> + </widget> + <widget class="QLabel" row="2" column="2"> + <property name="name"> + <cstring>textLabel1_4_2</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <spacer row="3" column="1"> + <property name="name"> + <cstring>spacer16</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>5</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>TabPage</cstring> + </property> + <attribute name="title"> + <string>V4L Mixer Controls</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout35</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>3</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>labelDeviceVolume</cstring> + </property> + <property name="text"> + <string>volume</string> + </property> + <property name="alignment"> + <set>AlignCenter</set> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout34</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>spacer42</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QSlider"> + <property name="name"> + <cstring>sliderDeviceVolume</cstring> + </property> + <property name="maxValue"> + <number>100</number> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer43</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="KDoubleNumInput"> + <property name="name"> + <cstring>editDeviceVolume</cstring> + </property> + <property name="maxValue"> + <number>1</number> + </property> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget" row="0" column="1"> + <property name="name"> + <cstring>layout35_2</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>3</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>labelTreble</cstring> + </property> + <property name="text"> + <string>treble</string> + </property> + <property name="alignment"> + <set>AlignCenter</set> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout34_2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>spacer42_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QSlider"> + <property name="name"> + <cstring>sliderTreble</cstring> + </property> + <property name="maxValue"> + <number>100</number> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer43_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="KDoubleNumInput"> + <property name="name"> + <cstring>editTreble</cstring> + </property> + <property name="maxValue"> + <number>1</number> + </property> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget" row="0" column="2"> + <property name="name"> + <cstring>layout35_2_2</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>3</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>labelBass</cstring> + </property> + <property name="text"> + <string>bass</string> + </property> + <property name="alignment"> + <set>AlignCenter</set> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout34_2_3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>spacer42_2_3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QSlider"> + <property name="name"> + <cstring>sliderBass</cstring> + </property> + <property name="maxValue"> + <number>100</number> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer43_2_3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="KDoubleNumInput"> + <property name="name"> + <cstring>editBass</cstring> + </property> + <property name="maxValue"> + <number>1</number> + </property> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget" row="0" column="3"> + <property name="name"> + <cstring>layout51</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="spacing"> + <number>3</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>labelBalance</cstring> + </property> + <property name="text"> + <string>balance</string> + </property> + <property name="alignment"> + <set>AlignCenter</set> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer40</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>33</height> + </size> + </property> + </spacer> + <widget class="QSlider"> + <property name="name"> + <cstring>sliderBalance</cstring> + </property> + <property name="minValue"> + <number>0</number> + </property> + <property name="maxValue"> + <number>65535</number> + </property> + <property name="pageStep"> + <number>1</number> + </property> + <property name="value"> + <number>0</number> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer41</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>33</height> + </size> + </property> + </spacer> + <widget class="KDoubleNumInput"> + <property name="name"> + <cstring>editBalance</cstring> + </property> + <property name="minValue"> + <number>-1</number> + </property> + <property name="maxValue"> + <number>1</number> + </property> + </widget> + </vbox> + </widget> + </grid> + </widget> + </widget> + </grid> +</widget> +<customwidgets> +</customwidgets> +<tabstops> + <tabstop>editRadioDevice</tabstop> + <tabstop>buttonSelectRadioDevice</tabstop> + <tabstop>comboPlaybackMixerChannel</tabstop> + <tabstop>editMinFrequency</tabstop> + <tabstop>editMaxFrequency</tabstop> + <tabstop>editSignalMinQuality</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">kiconloader.h</include> + <include location="global" impldecl="in implementation">knuminput.h</include> +</includes> +<pixmapfunction>SmallIconSet</pixmapfunction> +<layoutdefaults spacing="6" margin="0"/> +<includehints> + <includehint>ktabwidget.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> + <includehint>knuminput.h</includehint> +</includehints> +</UI> diff --git a/kradio3/plugins/v4lradio/v4lradio-configuration.cpp b/kradio3/plugins/v4lradio/v4lradio-configuration.cpp new file mode 100644 index 0000000..f7472fc --- /dev/null +++ b/kradio3/plugins/v4lradio/v4lradio-configuration.cpp @@ -0,0 +1,648 @@ +/*************************************************************************** + v4lradio-configuration.cpp - description + ------------------- + begin : Fre Jun 20 2003 + copyright : (C) 2003 by Martin Witte + email : witte@kawo1.rwth-aachen.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include <sys/ioctl.h> +#include <fcntl.h> +#include <unistd.h> +#include <linux/soundcard.h> + +#include <qspinbox.h> +#include <qlineedit.h> +#include <qcombobox.h> +#include <qlabel.h> +#include <qfile.h> +#include <qpushbutton.h> +#include <qslider.h> +#include <qcheckbox.h> + +#include <kfiledialog.h> +#include <knuminput.h> +#include <klocale.h> +#include <ktabwidget.h> + +#include "../../src/include/utils.h" +#include "../../src/include/gui_list_helper.h" +#include "v4lradio-configuration.h" +#include "v4lradio.h" + +V4LRadioConfiguration::V4LRadioConfiguration (QWidget *parent, SoundStreamID ssid) + : V4LRadioConfigurationUI(parent), + m_SoundStreamID(ssid), + m_ignoreGUIChanges(false), + m_myControlChange(0), + m_orgTreble(-1), + m_orgBass(-1), + m_orgBalance(-2), + m_orgDeviceVolume(-1), + m_PlaybackMixerHelper(comboPlaybackMixerDevice, StringListHelper::SORT_BY_DESCR), + m_CaptureMixerHelper (comboCaptureMixerDevice, StringListHelper::SORT_BY_DESCR), + m_PlaybackChannelHelper(comboPlaybackMixerChannel), + m_CaptureChannelHelper (comboCaptureMixerChannel) +{ + QObject::connect(buttonSelectRadioDevice, SIGNAL(clicked()), + this, SLOT(selectRadioDevice())); + editRadioDevice->installEventFilter(this); + QObject::connect(editMinFrequency, SIGNAL(valueChanged(int)), + this, SLOT(guiMinFrequencyChanged(int))); + QObject::connect(editMaxFrequency, SIGNAL(valueChanged(int)), + this, SLOT(guiMaxFrequencyChanged(int))); + + QObject::connect(editDeviceVolume, SIGNAL(valueChanged(double)), + this, SLOT(slotDeviceVolumeChanged(double))); + QObject::connect(editTreble, SIGNAL(valueChanged(double)), + this, SLOT(slotTrebleChanged(double))); + QObject::connect(editBass, SIGNAL(valueChanged(double)), + this, SLOT(slotBassChanged(double))); + QObject::connect(editBalance, SIGNAL(valueChanged(double)), + this, SLOT(slotBalanceChanged(double))); + + QObject::connect(sliderDeviceVolume, SIGNAL(valueChanged(int)), + this, SLOT(slotDeviceVolumeChanged(int))); + QObject::connect(sliderTreble, SIGNAL(valueChanged(int)), + this, SLOT(slotTrebleChanged(int))); + QObject::connect(sliderBass, SIGNAL(valueChanged(int)), + this, SLOT(slotBassChanged(int))); + QObject::connect(sliderBalance, SIGNAL(valueChanged(int)), + this, SLOT(slotBalanceChanged(int))); + + QObject::connect(comboPlaybackMixerDevice, SIGNAL(activated(int)), + this, SLOT(slotComboPlaybackMixerSelected(int))); + QObject::connect(comboCaptureMixerDevice, SIGNAL(activated(int)), + this, SLOT(slotComboCaptureMixerSelected(int))); + + sliderBalance->installEventFilter(this); +} + + +V4LRadioConfiguration::~V4LRadioConfiguration () +{ +} + + +bool V4LRadioConfiguration::connectI (Interface *i) +{ + bool a = IV4LCfgClient::connectI(i); + bool b = IFrequencyRadioClient::connectI(i); + bool c = IRadioDeviceClient::connectI(i); + bool d = ISoundStreamClient::connectI(i); + return a || b || c || d; +} + + +bool V4LRadioConfiguration::disconnectI (Interface *i) +{ + bool a = IV4LCfgClient::disconnectI(i); + bool b = IFrequencyRadioClient::disconnectI(i); + bool c = IRadioDeviceClient::disconnectI(i); + bool d = ISoundStreamClient::disconnectI(i); + return a || b || c || d; +} + +void V4LRadioConfiguration::noticeConnectedI (ISoundStreamServer *s, bool pointer_valid) +{ + ISoundStreamClient::noticeConnectedI(s, pointer_valid); + if (s && pointer_valid) { + s->register4_notifyTrebleChanged(this); + s->register4_notifyBassChanged(this); + s->register4_notifyBalanceChanged(this); + s->register4_notifySignalMinQualityChanged(this); + + s->register4_notifyPlaybackChannelsChanged(this); + s->register4_notifyCaptureChannelsChanged(this); + s->register4_notifySoundStreamCreated(this); + } +} + +void V4LRadioConfiguration::noticeConnectedSoundClient(ISoundStreamClient::thisInterface *i, bool pointer_valid) +{ + if (i && pointer_valid && i->supportsPlayback()) { + const QString &org_mid = queryPlaybackMixerID(); + bool org_present = m_PlaybackMixerHelper.contains(org_mid); + const QString &mid = org_present ? m_PlaybackMixerHelper.getCurrentItem() : org_mid; + const QString &org_ch = queryPlaybackMixerChannel(); + const QString &ch = org_present ? m_PlaybackChannelHelper.getCurrentText() : org_ch; + noticePlaybackMixerChanged(mid, ch); + } + if (i && pointer_valid && i->supportsCapture()) { + const QString &org_mid = queryCaptureMixerID(); + bool org_present = m_CaptureMixerHelper.contains(org_mid); + const QString &mid = org_present ? m_CaptureMixerHelper.getCurrentItem() : org_mid; + const QString &org_ch = queryCaptureMixerChannel(); + const QString &ch = org_present ? m_CaptureChannelHelper.getCurrentText() : org_ch; + noticeCaptureMixerChanged(mid, ch); + } +} + + +void V4LRadioConfiguration::noticeDisconnectedSoundClient(ISoundStreamClient::thisInterface *i, bool pointer_valid) +{ + if (i && pointer_valid && i->supportsPlayback()) { + noticePlaybackMixerChanged(queryPlaybackMixerID(), queryPlaybackMixerChannel()); + } + if (i && pointer_valid && i->supportsCapture()) { + noticeCaptureMixerChanged (queryCaptureMixerID(), queryCaptureMixerChannel()); + } +} + +// IV4LCfgClient + +bool V4LRadioConfiguration::noticeRadioDeviceChanged(const QString &s) +{ + bool old = m_ignoreGUIChanges; + m_ignoreGUIChanges = true; + + editRadioDevice->setText(s); + + m_ignoreGUIChanges = old; + return true; +} + + +bool V4LRadioConfiguration::noticePlaybackMixerChanged(const QString &_mixer_id, const QString &Channel) +{ + QString mixer_id = _mixer_id; + bool old = m_ignoreGUIChanges; + m_ignoreGUIChanges = true; + + m_PlaybackMixerHelper.setData(getPlaybackClientDescriptions()); + m_PlaybackMixerHelper.setCurrentItem(mixer_id); + mixer_id = m_PlaybackMixerHelper.getCurrentItem(); + + ISoundStreamClient *mixer = getSoundStreamClientWithID(mixer_id); + if (mixer) { + m_PlaybackChannelHelper.setData(mixer->getPlaybackChannels()); + m_PlaybackChannelHelper.setCurrentText(m_PlaybackChannelHelper.contains(Channel) ? Channel : queryPlaybackMixerChannel()); + } + labelPlaybackMixerChannel->setEnabled(mixer != NULL); + comboPlaybackMixerChannel->setEnabled(mixer != NULL); + + m_ignoreGUIChanges = old; + return true; +} + + +bool V4LRadioConfiguration::noticeCaptureMixerChanged(const QString &_mixer_id, const QString &Channel) +{ + QString mixer_id = _mixer_id; + bool old = m_ignoreGUIChanges; + m_ignoreGUIChanges = true; + + m_CaptureMixerHelper.setData(getCaptureClientDescriptions()); + m_CaptureMixerHelper.setCurrentItem(mixer_id); + mixer_id = m_CaptureMixerHelper.getCurrentItem(); + + ISoundStreamClient *mixer = getSoundStreamClientWithID(mixer_id); + if (mixer) { + m_CaptureChannelHelper.setData(mixer->getCaptureChannels()); + m_CaptureChannelHelper.setCurrentText(m_CaptureChannelHelper.contains(Channel) ? Channel : queryCaptureMixerChannel()); + } + labelCaptureMixerChannel->setEnabled(mixer != NULL); + comboCaptureMixerChannel->setEnabled(mixer != NULL); + + m_ignoreGUIChanges = old; + return true; +} + + +bool V4LRadioConfiguration::noticeDeviceVolumeChanged(float v) +{ + bool old = m_ignoreGUIChanges; + m_ignoreGUIChanges = true; + v = v > 1 ? 1 : v; + v = v < 0 ? 0 : v; + + if (!m_myControlChange) + m_orgDeviceVolume = v; + + editDeviceVolume ->setValue(v); + sliderDeviceVolume->setValue(m_caps.maxVolume - m_caps.intGetVolume(v)); + m_ignoreGUIChanges = old; + return true; +} + + +bool V4LRadioConfiguration::noticeCapabilitiesChanged(const V4LCaps &c) +{ + bool old = m_ignoreGUIChanges; + m_ignoreGUIChanges = true; + + labelDeviceVolume ->setEnabled(c.hasVolume); + editDeviceVolume ->setEnabled(c.hasVolume); + editDeviceVolume ->setRange(0, 1, c.volumeStep(), false); + sliderDeviceVolume->setMinValue(0); + sliderDeviceVolume->setMaxValue(c.maxVolume - c.minVolume); + sliderDeviceVolume->setEnabled(c.hasVolume); + + labelTreble ->setEnabled(c.hasTreble); + editTreble ->setEnabled(c.hasTreble); + editTreble ->setRange(0, 1, c.trebleStep(), false); + sliderTreble->setMinValue(0); + sliderTreble->setMaxValue(c.maxTreble - c.minTreble); + sliderTreble->setEnabled(c.hasTreble); + + labelBass ->setEnabled(c.hasBass); + editBass ->setEnabled(c.hasBass); + editBass ->setRange(0, 1, c.bassStep(), false); + sliderBass->setMinValue(0); + sliderBass->setMaxValue(c.maxBass - c.minBass); + sliderBass->setEnabled(c.hasBass); + + labelBalance ->setEnabled(c.hasBalance); + editBalance ->setEnabled(c.hasBalance); + editBalance ->setRange(-1, 1, c.balanceStep(), false); + sliderBalance->setMinValue(0); + sliderBalance->setMaxValue(c.maxBalance - c.minBalance); + sliderBalance->setEnabled(c.hasBalance); + + m_caps = c; + + float tmp = 0; + noticeDeviceVolumeChanged(queryDeviceVolume()); + + queryTreble(m_SoundStreamID, tmp); + noticeTrebleChanged(m_SoundStreamID, tmp); + + queryBass(m_SoundStreamID, tmp); + noticeBassChanged(m_SoundStreamID, tmp); + + queryBalance(m_SoundStreamID, tmp); + noticeBalanceChanged(m_SoundStreamID, tmp); + + m_ignoreGUIChanges = old; + return true; +} + +bool V4LRadioConfiguration::noticeActivePlaybackChanged(bool a) +{ + bool old = m_ignoreGUIChanges; + m_ignoreGUIChanges = true; + m_checkboxActivePlayback->setChecked(a); + m_ignoreGUIChanges = old; + return true; +} + +bool V4LRadioConfiguration::noticeMuteOnPowerOffChanged(bool a) +{ + bool old = m_ignoreGUIChanges; + m_ignoreGUIChanges = true; + m_checkboxMuteOnPowerOff->setChecked(a); + m_ignoreGUIChanges = old; + return true; +} + +bool V4LRadioConfiguration::noticeVolumeZeroOnPowerOffChanged(bool a) +{ + bool old = m_ignoreGUIChanges; + m_ignoreGUIChanges = true; + m_checkboxVolumeZeroOnPowerOff->setChecked(a); + m_ignoreGUIChanges = old; + return true; +} + +// IRadioDeviceClient + +bool V4LRadioConfiguration::noticeDescriptionChanged (const QString &s, const IRadioDevice */*sender*/) +{ + labelDescription->setText(s); + return true; +} + + +// IFrequencyRadioClient + +bool V4LRadioConfiguration::noticeFrequencyChanged(float /*f*/, const RadioStation */*s*/) +{ + return false; // we don't care +} + + +bool V4LRadioConfiguration::noticeMinMaxFrequencyChanged(float min, float max) +{ + editMinFrequency->setValue((int)rint(min*1000)); + editMaxFrequency->setValue((int)rint(max*1000)); + return true; +} + + +bool V4LRadioConfiguration::noticeDeviceMinMaxFrequencyChanged(float min, float max) +{ + editMinFrequency->setMinValue((int)rint(min*1000)); + editMaxFrequency->setMaxValue((int)rint(max*1000)); + return true; +} + + +bool V4LRadioConfiguration::noticeScanStepChanged(float s) +{ + editScanStep->setValue((int)rint(s * 1000)); + return true; +} + + +// IRadioSoundClient + +bool V4LRadioConfiguration::noticeTrebleChanged(SoundStreamID id, float t) +{ + if (id != m_SoundStreamID) + return false; + + bool old = m_ignoreGUIChanges; + m_ignoreGUIChanges = true; + t = t > 1 ? 1 : t; + t = t < 0 ? 0 : t; + + if (!m_myControlChange) + m_orgTreble = t; + + editTreble ->setValue (t); + sliderTreble->setValue(m_caps.maxTreble - m_caps.intGetTreble(t)); + m_ignoreGUIChanges = old; + return true; +} + + +bool V4LRadioConfiguration::noticeBassChanged(SoundStreamID id, float b) +{ + if (id != m_SoundStreamID) + return false; + + bool old = m_ignoreGUIChanges; + m_ignoreGUIChanges = true; + b = b > 1 ? 1 : b; + b = b < 0 ? 0 : b; + + if (!m_myControlChange) + m_orgBass = b; + + editBass ->setValue(b); + sliderBass->setValue(m_caps.maxBass - m_caps.intGetBass(b)); + m_ignoreGUIChanges = old; + return true; +} + + +bool V4LRadioConfiguration::noticeBalanceChanged(SoundStreamID id, float b) +{ + if (id != m_SoundStreamID) + return false; + + bool old = m_ignoreGUIChanges; + m_ignoreGUIChanges = true; + b = b > 1 ? 1 : b; + b = b < -1 ? -1 : b; + + if (!m_myControlChange) + m_orgBalance = b; + + editBalance ->setValue(b); + sliderBalance->setValue(m_caps.intGetBalance(b)); + m_ignoreGUIChanges = old; + return true; +} + + +bool V4LRadioConfiguration::noticeSignalMinQualityChanged(SoundStreamID id, float q) +{ + if (id != m_SoundStreamID) + return false; + + editSignalMinQuality->setValue((int)rint(q * 100)); + return true; +} + + +bool V4LRadioConfiguration::noticeSoundStreamCreated(SoundStreamID id) +{ + if (id.HasSamePhysicalID(m_SoundStreamID)) { + m_SoundStreamID = id; + } + return true; +} + + +// GUI Slots + + +void V4LRadioConfiguration::selectRadioDevice() +{ + KFileDialog fd("/dev/", + i18n("any ( * )").ascii(), + this, + i18n("Radio Device Selection").ascii(), + TRUE); + fd.setMode(KFile::File | KFile::ExistingOnly); + fd.setCaption (i18n("Select Radio Device")); + + if (fd.exec() == QDialog::Accepted) { + editRadioDevice->setText(fd.selectedFile()); + } +} + + +bool V4LRadioConfiguration::eventFilter(QObject *o, QEvent *e) +{ + if (e->type() == QEvent::FocusOut && o == editRadioDevice) { + slotEditRadioDeviceChanged(); + } + if (e->type() == QEvent::MouseButtonDblClick && o == sliderBalance) { + slotBalanceCenter(); + } + return false; +} + + +void V4LRadioConfiguration::slotEditRadioDeviceChanged() +{ + if (m_ignoreGUIChanges) return; + const QString &s = editRadioDevice->text(); + if (s != queryRadioDevice() || !queryIsPowerOn()) { + V4LCaps c = queryCapabilities(s); + noticeDescriptionChanged(c.description); + } else { + noticeDescriptionChanged(queryDescription()); + } +} + + +void V4LRadioConfiguration::slotComboPlaybackMixerSelected(int /*idx*/) +{ + if (m_ignoreGUIChanges) return; + QString id = m_PlaybackMixerHelper.getCurrentItem(); + noticePlaybackMixerChanged(id, queryPlaybackMixerChannel()); +} + + +void V4LRadioConfiguration::slotComboCaptureMixerSelected(int /*idx*/) +{ + if (m_ignoreGUIChanges) return; + QString id = m_CaptureMixerHelper.getCurrentItem(); + noticeCaptureMixerChanged(id, queryCaptureMixerChannel()); +} + + +void V4LRadioConfiguration::slotOK() +{ + sendMinFrequency(((float)editMinFrequency->value()) / 1000.0); + sendMaxFrequency(((float)editMaxFrequency->value()) / 1000.0); + sendSignalMinQuality(m_SoundStreamID, editSignalMinQuality->value() * 0.01); + sendRadioDevice(editRadioDevice->text()); + sendScanStep(((float)editScanStep->value()) / 1000.0); + + sendCaptureMixer (m_CaptureMixerHelper.getCurrentItem(), + m_CaptureChannelHelper.getCurrentText()); + sendPlaybackMixer(m_PlaybackMixerHelper.getCurrentItem(), + m_PlaybackChannelHelper.getCurrentText()); + + sendActivePlayback(m_checkboxActivePlayback->isChecked()); + sendMuteOnPowerOff(m_checkboxMuteOnPowerOff->isChecked()); + sendVolumeZeroOnPowerOff(m_checkboxVolumeZeroOnPowerOff->isChecked()); + + queryTreble (m_SoundStreamID, m_orgTreble); + queryBass (m_SoundStreamID, m_orgBass); + queryBalance(m_SoundStreamID, m_orgBalance); + m_orgDeviceVolume = queryDeviceVolume(); +} + + +void V4LRadioConfiguration::slotCancel() +{ + noticeRadioDeviceChanged(queryRadioDevice()); + noticePlaybackMixerChanged(queryPlaybackMixerID(), queryPlaybackMixerChannel()); + noticeCaptureMixerChanged (queryCaptureMixerID(), queryCaptureMixerChannel()); + noticeMinMaxFrequencyChanged(queryMinFrequency(), queryMaxFrequency()); + noticeActivePlaybackChanged(queryActivePlayback()); + noticeMuteOnPowerOffChanged(queryMuteOnPowerOff()); + noticeVolumeZeroOnPowerOffChanged(queryVolumeZeroOnPowerOff()); + + float q = 0; + querySignalMinQuality(m_SoundStreamID, q); + noticeSignalMinQualityChanged(m_SoundStreamID, q); + noticeScanStepChanged(queryScanStep()); + + sendTreble (m_SoundStreamID, m_orgTreble); + sendBass (m_SoundStreamID, m_orgBass); + sendBalance (m_SoundStreamID, m_orgBalance); + sendDeviceVolume(m_orgDeviceVolume); +} + + +void V4LRadioConfiguration::guiMinFrequencyChanged(int v) +{ + editMaxFrequency->setMinValue(v); +} + + +void V4LRadioConfiguration::guiMaxFrequencyChanged(int v) +{ + editMinFrequency->setMaxValue(v); +} + +void V4LRadioConfiguration::slotDeviceVolumeChanged (double v) // for KDoubleNumInput, 0.0..1.0 +{ + if (m_ignoreGUIChanges) return; + ++m_myControlChange; + sendDeviceVolume(v); + --m_myControlChange; +} + +void V4LRadioConfiguration::slotTrebleChanged (double t) // for KDoubleNumInput, 0.0..1.0 +{ + if (m_ignoreGUIChanges) return; + ++m_myControlChange; + sendTreble(m_SoundStreamID, t); + --m_myControlChange; +} + +void V4LRadioConfiguration::slotBassChanged (double b) // for KDoubleNumInput, 0.0..1.0 +{ + if (m_ignoreGUIChanges) return; + ++m_myControlChange; + sendBass(m_SoundStreamID, b); + --m_myControlChange; +} + +void V4LRadioConfiguration::slotBalanceChanged(double b) // for KDoubleNumInput, -1.0..1.0 +{ + if (m_ignoreGUIChanges) return; + ++m_myControlChange; + sendBalance(m_SoundStreamID, b); + --m_myControlChange; +} + + +void V4LRadioConfiguration::slotDeviceVolumeChanged (int v) +{ + if (m_ignoreGUIChanges) return; + ++m_myControlChange; + sendDeviceVolume(m_caps.floatGetVolume(m_caps.maxVolume - v)); + --m_myControlChange; +} + +void V4LRadioConfiguration::slotTrebleChanged (int t) +{ + if (m_ignoreGUIChanges) return; + ++m_myControlChange; + sendTreble(m_SoundStreamID, m_caps.floatGetTreble(m_caps.maxTreble - t)); + --m_myControlChange; +} + +void V4LRadioConfiguration::slotBassChanged (int b) +{ + if (m_ignoreGUIChanges) return; + ++m_myControlChange; + sendBass(m_SoundStreamID, m_caps.floatGetBass(m_caps.maxBass - b)); + --m_myControlChange; +} + +void V4LRadioConfiguration::slotBalanceChanged(int b) +{ + if (m_ignoreGUIChanges) return; + ++m_myControlChange; + sendBalance(m_SoundStreamID, m_caps.floatGetBalance(b)); + --m_myControlChange; +} + + +void V4LRadioConfiguration::slotBalanceCenter() +{ + if (m_ignoreGUIChanges) return; + ++m_myControlChange; + sendBalance(m_SoundStreamID, 0); + --m_myControlChange; +} + + +bool V4LRadioConfiguration::noticePlaybackChannelsChanged(const QString & client_id, const QStringList &/*channels*/) +{ + if (m_PlaybackMixerHelper.getCurrentItem() == client_id) { + noticePlaybackMixerChanged(client_id, m_PlaybackChannelHelper.getCurrentText()); + } + return true; +} + + +bool V4LRadioConfiguration::noticeCaptureChannelsChanged (const QString & client_id, const QStringList &/*channels*/) +{ + if (m_CaptureMixerHelper.getCurrentItem() == client_id) { + noticeCaptureMixerChanged(client_id, m_CaptureChannelHelper.getCurrentText()); + } + return true; +} + + + +#include "v4lradio-configuration.moc" diff --git a/kradio3/plugins/v4lradio/v4lradio-configuration.h b/kradio3/plugins/v4lradio/v4lradio-configuration.h new file mode 100644 index 0000000..bf41b54 --- /dev/null +++ b/kradio3/plugins/v4lradio/v4lradio-configuration.h @@ -0,0 +1,147 @@ +/*************************************************************************** + v4lradio-configuration.h - description + ------------------- + begin : Fre Jun 20 2003 + copyright : (C) 2003 by Martin Witte + email : witte@kawo1.rwth-aachen.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KRADIO_V4LRADIO_CONFIGURATION_H +#define KRADIO_V4LRADIO_CONFIGURATION_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "../../src/include/radiodevice_interfaces.h" +#include "../../src/include/soundstreamclient_interfaces.h" +#include "../../src/include/gui_list_helper.h" + +#include "v4lradio-configuration-ui.h" +#include "v4lcfg_interfaces.h" + +class V4LRadio; +class QWidget; + +class V4LRadioConfiguration : public V4LRadioConfigurationUI, + public IV4LCfgClient, + public IFrequencyRadioClient, + public ISoundStreamClient, + public IRadioDeviceClient +{ +Q_OBJECT +public : + V4LRadioConfiguration (QWidget *parent, SoundStreamID id); + ~V4LRadioConfiguration (); + + bool connectI (Interface *i); + bool disconnectI (Interface *i); + + void noticeConnectedSoundClient(ISoundStreamClient::thisInterface *i, bool pointer_valid); + void noticeDisconnectedSoundClient(ISoundStreamClient::thisInterface *i, bool pointer_valid); + +// IV4LCfgClient + +RECEIVERS: + bool noticeRadioDeviceChanged(const QString &s); + bool noticePlaybackMixerChanged(const QString &soundStreamClientID, const QString &Channel); + bool noticeCaptureMixerChanged (const QString &soundStreamClientID, const QString &Channel); + bool noticeDeviceVolumeChanged(float v); + bool noticeCapabilitiesChanged(const V4LCaps &c); + bool noticeActivePlaybackChanged(bool a); + bool noticeMuteOnPowerOffChanged(bool a); + bool noticeVolumeZeroOnPowerOffChanged(bool a); + +// IRadioDeviceClient + +RECEIVERS: + bool noticePowerChanged (bool /*on*/, const IRadioDevice */*sender = NULL*/) { return false; } + bool noticeStationChanged (const RadioStation &, const IRadioDevice */*sender = NULL*/) { return false; } + bool noticeDescriptionChanged (const QString &, const IRadioDevice *sender = NULL); + + bool noticeCurrentSoundStreamIDChanged(SoundStreamID /*id*/, const IRadioDevice */*sender*/) { return false; } + +// IFrequencyRadioClient + +RECEIVERS: + bool noticeFrequencyChanged(float f, const RadioStation *s); + bool noticeMinMaxFrequencyChanged(float min, float max); + bool noticeDeviceMinMaxFrequencyChanged(float min, float max); + bool noticeScanStepChanged(float s); + +// ISoundStreamClient + +RECEIVERS: + void noticeConnectedI (ISoundStreamServer *s, bool pointer_valid); + + bool noticeTrebleChanged(SoundStreamID id, float t); + bool noticeBassChanged(SoundStreamID id, float b); + bool noticeBalanceChanged(SoundStreamID id, float b); + bool noticeSignalMinQualityChanged(SoundStreamID id, float q); + + bool noticePlaybackChannelsChanged(const QString & /*client_id*/, const QStringList &/*channels*/); + bool noticeCaptureChannelsChanged (const QString & /*client_id*/, const QStringList &/*channels*/); + bool noticeSoundStreamCreated(SoundStreamID /*id*/); + + +protected: + + bool eventFilter(QObject *o, QEvent *e); + +protected slots: + + void selectRadioDevice(); + void slotEditRadioDeviceChanged(); + void slotComboPlaybackMixerSelected(int idx); + void slotComboCaptureMixerSelected(int idx); + + void slotOK(); + void slotCancel(); + + void guiMinFrequencyChanged(int v); + void guiMaxFrequencyChanged(int v); + + void slotDeviceVolumeChanged (double v); // for KDoubleNumInput, 0.0..1.0 + void slotTrebleChanged (double t); // for KDoubleNumInput, 0.0..1.0 + void slotBassChanged (double b); // for KDoubleNumInput, 0.0..1.0 + void slotBalanceChanged(double b); // for KDoubleNumInput, -1.0..1.0 + + void slotDeviceVolumeChanged (int v); // for slider, 0..65535 + void slotTrebleChanged (int t); // for slider, 0..65535 + void slotBassChanged (int b); // for slider, 0..65535 + void slotBalanceChanged(int b); // for slider, 0..65535 + void slotBalanceCenter (); + +protected: + + SoundStreamID m_SoundStreamID; + + bool m_ignoreGUIChanges; + + int m_myControlChange; + float m_orgTreble, + m_orgBass, + m_orgBalance, + m_orgDeviceVolume; + + V4LCaps m_caps; + + typedef GUIListHelper<QComboBox, QString> StringListHelper; + typedef GUISimpleListHelper<QComboBox> ChannelListHelper; + + StringListHelper m_PlaybackMixerHelper, + m_CaptureMixerHelper; + ChannelListHelper m_PlaybackChannelHelper, + m_CaptureChannelHelper; +}; + +#endif diff --git a/kradio3/plugins/v4lradio/v4lradio.cpp b/kradio3/plugins/v4lradio/v4lradio.cpp new file mode 100644 index 0000000..fb1ee9f --- /dev/null +++ b/kradio3/plugins/v4lradio/v4lradio.cpp @@ -0,0 +1,1621 @@ +/*************************************************************************** + v4lradio.cpp - description + ------------------- + begin : Don Mr 8 21:57:17 CET 2001 + copyright : (C) 2002-2005 by Ernst Martin Witte + email : witte@kawo1.rwth-aachen.de + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <fcntl.h> +#include <sys/ioctl.h> +#include <unistd.h> + +#ifdef HAVE_V4L2 +#include "linux/videodev2.h" +#endif +#include "linux/videodev.h" +#include <linux/soundcard.h> + +#include <string.h> // memcpy needed + +#include <qlayout.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qvaluelist.h> + +#include <kconfig.h> +#include <kiconloader.h> +#include <kdialogbase.h> +#include <kaboutdata.h> +#include <klocale.h> + +#include "../../src/include/aboutwidget.h" +#include "../../src/include/utils.h" +#include "v4lradio.h" +#include "v4lradio-configuration.h" + +#include "../../src/include/debug-profiler.h" + +struct _lrvol { unsigned char l, r; short dummy; }; + +/////////////////////////////////////////////////////////////////////// + +PLUGIN_LIBRARY_FUNCTIONS(V4LRadio, "kradio-v4lradio", i18n("Support for V4L(2) Radio Devices")); + +/////////////////////////////////////////////////////////////////////// + +V4LRadio::V4LRadio(const QString &name) + : PluginBase(name, i18n("Video For Linux Plugin")), + m_treble(0.5), + m_bass(0.5), + m_balance(0), + m_deviceVolume(0.9), + m_muted(false), + m_signalQuality(0), + m_stereo(false), + m_minQuality(0.75), + m_minFrequency(87.0), + m_maxFrequency(108.0), + m_lastMinDevFrequency(87.0), + m_lastMaxDevFrequency(108.0), + + m_defaultPlaybackVolume(0.5), + + m_scanStep(0.05), + + m_radioDev("/dev/radio0"), + m_radio_fd(-1), + m_useOldV4L2Calls(true), + m_pollTimer(this), + + m_blockReadTuner(false), + m_blockReadAudio(false), + + m_SoundStreamID(createNewSoundStream(false)), + m_PlaybackMixerID(QString::null), + m_CaptureMixerID(QString::null), + m_PlaybackMixerChannel(QString::null), + m_CaptureMixerChannel(QString::null), + m_ActivePlayback(false), + m_MuteOnPowerOff(false), + m_VolumeZeroOnPowerOff(false), + m_restorePowerOn(false) +{ + QObject::connect (&m_pollTimer, SIGNAL(timeout()), this, SLOT(poll())); + m_pollTimer.start(333); + + m_audio = new video_audio; + bzero(m_audio, sizeof(video_audio)); + m_tuner = new video_tuner; + bzero(m_tuner, sizeof(video_tuner)); +#ifdef HAVE_V4L2 + m_tuner2 = new v4l2_tuner; + bzero(m_tuner2, sizeof(v4l2_tuner)); +#endif + m_caps.version = 0; + + m_seekHelper = new FrequencySeekHelper(*this); + m_seekHelper->connectI(this); +} + + +V4LRadio::~V4LRadio() +{ + setPower(false); + + if (m_seekHelper) + delete m_seekHelper; + + if (m_audio) delete m_audio; + if (m_tuner) delete m_tuner; +#ifdef HAVE_V4L2 + if (m_tuner2) delete m_tuner2; +#endif +} + + +bool V4LRadio::connectI (Interface *i) +{ + bool a = IRadioDevice::connectI(i); + bool b = ISeekRadio::connectI(i); + bool c = IFrequencyRadio::connectI(i); + bool d = IV4LCfg::connectI(i); + bool e = PluginBase::connectI(i); + bool f = ISoundStreamClient::connectI(i); + return a || b || c || d || e || f; +} + + +bool V4LRadio::disconnectI (Interface *i) +{ + bool a = IRadioDevice::disconnectI(i); + bool b = ISeekRadio::disconnectI(i); + bool c = IFrequencyRadio::disconnectI(i); + bool d = IV4LCfg::disconnectI(i); + bool e = PluginBase::disconnectI(i); + bool f = ISoundStreamClient::disconnectI(i); + m_seekHelper->disconnectI(i); + return a || b || c || d || e || f; +} + + +void V4LRadio::noticeConnectedI (ISoundStreamServer *s, bool pointer_valid) +{ + ISoundStreamClient::noticeConnectedI(s, pointer_valid); + if (s && pointer_valid) { + m_seekHelper->connectI(s); + + s->register4_queryPlaybackVolume(this); + s->register4_sendTreble(this); + s->register4_sendBass(this); + s->register4_sendBalance(this); + s->register4_sendMute(this); + s->register4_sendUnmute(this); + s->register4_sendSignalMinQuality(this); + s->register4_sendStereo(this); + + s->register4_queryTreble(this); + s->register4_queryBass(this); + s->register4_queryBalance(this); + s->register4_querySignalQuality(this); + s->register4_querySignalMinQuality(this); + s->register4_queryHasGoodQuality(this); + s->register4_queryIsStereo(this); + s->register4_queryIsMuted(this); + + + s->register4_sendPlaybackVolume(this); + s->register4_sendCaptureVolume(this); + + s->register4_sendStopCapture(this); + + s->register4_querySoundStreamDescription(this); + s->register4_querySoundStreamRadioStation(this); + s->register4_queryEnumerateSoundStreams(this); + + notifySoundStreamCreated(m_SoundStreamID); + } +} + +void V4LRadio::noticeConnectedSoundClient(ISoundStreamClient::thisInterface *i, bool pointer_valid) +{ + if (i && pointer_valid && i->getSoundStreamClientID() == m_PlaybackMixerID) { + setPlaybackMixer(m_PlaybackMixerID, m_PlaybackMixerChannel); + } + if (i && pointer_valid && i->getSoundStreamClientID() == m_CaptureMixerID) { + setCaptureMixer(m_CaptureMixerID, m_CaptureMixerChannel); + } +} + +// IRadioDevice methods + +bool V4LRadio::setPower (bool on) +{ + return on ? powerOn() : powerOff(); +} + +void V4LRadio::searchMixers(ISoundStreamClient **playback_mixer, ISoundStreamClient **capture_mixer) +{ + if (playback_mixer) { + *playback_mixer = getSoundStreamClientWithID(m_PlaybackMixerID); + if (!*playback_mixer) { + QPtrList<ISoundStreamClient> playback_mixers = queryPlaybackMixers(); + if (!playback_mixers.isEmpty()) + *playback_mixer = playback_mixers.first(); + } + } + if (capture_mixer) { + *capture_mixer = getSoundStreamClientWithID(m_CaptureMixerID); + if (!*capture_mixer) { + QPtrList<ISoundStreamClient> capture_mixers = queryCaptureMixers(); + if (!capture_mixers.isEmpty()) + *capture_mixer = capture_mixers.first(); + } + } +} + + +bool V4LRadio::powerOn () +{ + if (isPowerOn()) + return true; + + radio_init(); + + if (isPowerOn()) { + ISoundStreamClient *playback_mixer = NULL, + *capture_mixer = NULL; + + searchMixers(&playback_mixer, &capture_mixer); + + if (playback_mixer) + playback_mixer->preparePlayback(m_SoundStreamID, m_PlaybackMixerChannel, m_ActivePlayback, false); + if (capture_mixer) + capture_mixer->prepareCapture(m_SoundStreamID, m_CaptureMixerChannel); + + sendStartPlayback(m_SoundStreamID); + float tmp_vol = 0; + queryPlaybackVolume(m_SoundStreamID, tmp_vol); + if (tmp_vol < 0.005) + sendPlaybackVolume(m_SoundStreamID, m_defaultPlaybackVolume); + + if (m_ActivePlayback) { + SoundFormat sf; + sendStartCaptureWithFormat(m_SoundStreamID, sf, sf); + } + + unmute(m_SoundStreamID); + notifyPowerChanged(true); + } + + return true; +} + + +bool V4LRadio::powerOff () +{ + if (! isPowerOn()) + return true; + + queryPlaybackVolume(m_SoundStreamID, m_defaultPlaybackVolume); + if (m_MuteOnPowerOff) + sendMute(m_SoundStreamID, true); + if (m_VolumeZeroOnPowerOff) + sendPlaybackVolume(m_SoundStreamID, 0.0); + mute(m_SoundStreamID); + radio_done(); + + sendStopPlayback(m_SoundStreamID); + sendStopCapture(m_SoundStreamID); + closeSoundStream(m_SoundStreamID); + m_SoundStreamID = createNewSoundStream(m_SoundStreamID, false); + notifySoundStreamCreated(m_SoundStreamID); + + if (isPowerOff()) { + notifyPowerChanged(false); + } + + return true; +} + + +bool V4LRadio::activateStation(const RadioStation &rs) +{ + const FrequencyRadioStation *frs = dynamic_cast<const FrequencyRadioStation*>(&rs); + if (frs == NULL) + return false; + + if (setFrequency(frs->frequency())) { + m_currentStation = *frs; + + if (frs->initialVolume() > 0) + setPlaybackVolume(m_SoundStreamID, frs->initialVolume()); + + return true; + } + + return false; +} + + + +bool V4LRadio::isPowerOn() const +{ + return m_radio_fd >= 0; +} + + +bool V4LRadio::isPowerOff() const +{ + return m_radio_fd < 0; +} + + +SoundStreamID V4LRadio::getSoundStreamID() const +{ + return m_SoundStreamID; +} + + +const RadioStation &V4LRadio::getCurrentStation() const +{ + return m_currentStation; +} + + +const QString &V4LRadio::getDescription() const +{ + return m_caps.description; +} + + +SoundStreamID V4LRadio::getCurrentSoundStreamID() const +{ + return m_SoundStreamID; +} + + + + +bool V4LRadio::setTreble (SoundStreamID id, float t) +{ + if (id != m_SoundStreamID) + return false; + + if (t > 1.0) t = 1.0; + if (t < 0) t = 0.0; + if ((int)rint(m_treble*65535) != (int)rint(t*65535)) { + m_treble = t; + writeAudioInfo(); + notifyTrebleChanged(id, t); + } + return true; +} + + +bool V4LRadio::setBass (SoundStreamID id, float b) +{ + if (id != m_SoundStreamID) + return false; + + if (b > 1.0) b = 1.0; + if (b < 0) b = 0.0; + if ((int)rint(m_bass*65535) != (int)rint(b*65535)) { + m_bass = b; + writeAudioInfo(); + notifyBassChanged(id, b); + } + + return true; +} + + +bool V4LRadio::setBalance (SoundStreamID id, float b) +{ + if (id != m_SoundStreamID) + return false; + + if (b > +1.0) b = +1.0; + if (b < -1.0) b = -1.0; + if ((int)rint(m_balance*32767) != (int)rint(b*32767)) { + m_balance = b; + writeAudioInfo(); + notifyBalanceChanged(id, b); + } + return true; +} + + +bool V4LRadio::setDeviceVolume (float v) +{ + if (v > 1.0) v = 1.0; + if (v < 0) v = 0; + if ((int)rint(m_deviceVolume*65535) != (int)rint(v*65535)) { + m_deviceVolume = v; + writeAudioInfo(); + notifyDeviceVolumeChanged(v); + } + return true; +} + + +bool V4LRadio::mute (SoundStreamID id, bool mute) +{ + if (id != m_SoundStreamID) + return false; + + if (m_muted != mute) { + m_muted = mute; + bool r = writeAudioInfo(); + if (r) + notifyMuted(id, m_muted); + return r; + } + return false; +} + + +bool V4LRadio::unmute (SoundStreamID id, bool unmute) +{ + return mute(id, !unmute); +} + + +bool V4LRadio::setSignalMinQuality (SoundStreamID id, float mq) +{ + if (id != m_SoundStreamID) + return false; + if (rint(mq*100) == rint(m_minQuality*100)) + return true; + + m_minQuality = mq; + notifySignalMinQualityChanged(id, m_minQuality); + return true; +} + + +bool V4LRadio::setStereo(SoundStreamID /*id*/, bool /*b*/) +{ + // FIXME if possible + return false; // we can't do that currently, not even switch stereo to mono +} + + + + +bool V4LRadio::getTreble (SoundStreamID id, float &t) const +{ + if (id != m_SoundStreamID) + return false; + + readAudioInfo(); + t = m_treble; + return true; +} + + +bool V4LRadio::getBass (SoundStreamID id, float &b) const +{ + if (id != m_SoundStreamID) + return false; + + readAudioInfo(); + b = m_bass; + return true; +} + + +bool V4LRadio::getBalance (SoundStreamID id, float &b) const +{ + if (id != m_SoundStreamID) + return false; + + readAudioInfo(); + b = m_balance; + return true; +} + + +float V4LRadio::getDeviceVolume () const +{ + readAudioInfo(); + return m_deviceVolume; +} + + + +bool V4LRadio::getSignalMinQuality(SoundStreamID id, float &q) const +{ + if (id != m_SoundStreamID) + return false; + + q = m_minQuality; + return true; +} + + +bool V4LRadio::getSignalQuality(SoundStreamID id, float &q) const +{ + if (id != m_SoundStreamID) + return false; + + readTunerInfo(); + q = m_signalQuality; + return true; +} + + +bool V4LRadio::hasGoodQuality(SoundStreamID id, bool &good) const +{ + if (id != m_SoundStreamID) + return false; + + float q = 0; + if (getSignalQuality(id, q)) + good = q >= m_minQuality; + return true; +} + + +bool V4LRadio::isStereo(SoundStreamID id, bool &s) const +{ + if (id != m_SoundStreamID) + return false; + + readAudioInfo(); + s = m_stereo; + return true; +} + + +bool V4LRadio::isMuted(SoundStreamID id, bool &m) const +{ + if (id != m_SoundStreamID) + return false; + + readAudioInfo(); + m = m_muted; + return true; +} + + +// ISeekRadio + +bool V4LRadio::toBeginning() +{ + setFrequency(getMinFrequency()); + return true; +} + +bool V4LRadio::toEnd() +{ + setFrequency(getMaxFrequency()); + return true; +} + +bool V4LRadio::startSeekUp() +{ + return startSeek(true); +} + +bool V4LRadio::startSeekDown() +{ + return startSeek(false); +} + +bool V4LRadio::startSeek(bool up) +{ + if (isPowerOn() && m_seekHelper) { + m_seekHelper->start(m_SoundStreamID, up ? SeekHelper::up : SeekHelper::down); + return true; + } else { + return false; + } +} + +bool V4LRadio::stopSeek() +{ + if (m_seekHelper) m_seekHelper->stop(); + return true; +} + +bool V4LRadio::isSeekRunning() const +{ + if (m_seekHelper) + return m_seekHelper->isRunning(); + else + return false; +} + + +bool V4LRadio::isSeekUpRunning() const +{ + if (m_seekHelper) + return m_seekHelper->isRunningUp(); + else + return false; +} + + +bool V4LRadio::isSeekDownRunning() const +{ + if (m_seekHelper) + return m_seekHelper->isRunningDown(); + else + return false; +} + +float V4LRadio::getProgress () const +{ + float min = getMinFrequency(); + float max = getMaxFrequency(); + + return (getFrequency() - min) / (max - min); +} + + +// IFrequencyRadio + +bool V4LRadio::setFrequency(float freq) +{ +// if (isSeekRunning()) +// stopSeek(); + + if (m_currentStation.frequency() == freq) { + return true; + } + + float minf = getMinFrequency(); + float maxf = getMaxFrequency(); + + if (isPowerOn()) { + + bool oldMute = false; + isMuted(m_SoundStreamID, oldMute); + if (!oldMute && !m_ActivePlayback) + mute(m_SoundStreamID); + + + if (!m_tunercache.valid) readTunerInfo(); + float df = m_tunercache.deltaF; + + unsigned long lfreq = (unsigned long) rint(freq / df); + + if (freq > maxf || freq < minf) { + logError("V4LRadio::setFrequency: " + + i18n("invalid frequency %1").arg(QString().setNum(freq))); + if (!oldMute && !m_ActivePlayback) + unmute(m_SoundStreamID); + return false; + } + + int r = -1; + if (m_caps.version == 1) { + r = ioctl(m_radio_fd, VIDIOCSFREQ, &lfreq); + } +#ifdef HAVE_V4L2 + else if (m_caps.version == 2) { + v4l2_frequency tmp; + tmp.tuner = 0; + tmp.type = V4L2_TUNER_RADIO; + tmp.frequency = lfreq; + r = ioctl(m_radio_fd, VIDIOC_S_FREQUENCY, &tmp); + } +#endif + else { + logError("V4LRadio::setFrequency: " + + i18n("don't known how to handle V4L-version %1") + .arg(m_caps.version)); + } + + if (r) { + logError("V4LRadio::setFrequency: " + + i18n("error setting frequency to %1 (%2)") + .arg(QString().setNum(freq)) + .arg(QString().setNum(r))); + // unmute the old radio with the old radio station + if (!oldMute && !m_ActivePlayback) + unmute(m_SoundStreamID); + return false; + } + + // unmute this radio device, because we now have the current + // radio station + if (!oldMute && !m_ActivePlayback) + unmute(m_SoundStreamID); + } + + m_currentStation.setFrequency(freq); + notifyFrequencyChanged(freq, &m_currentStation); + notifyStationChanged(m_currentStation); + notifyProgress((freq - minf) / (maxf - minf)); + notifySoundStreamChanged(m_SoundStreamID); + return true; +} + + +bool V4LRadio::setMinFrequency (float minF) +{ + float oldm = getMinFrequency(); + m_minFrequency = minF; + + float newm = getMinFrequency(); + if (oldm != newm) + notifyMinMaxFrequencyChanged(newm, getMaxFrequency()); + + return true; +} + + +bool V4LRadio::setMaxFrequency (float maxF) +{ + float oldm = getMaxFrequency(); + m_maxFrequency = maxF; + + float newm = getMaxFrequency(); + if (oldm != newm) + notifyMinMaxFrequencyChanged(getMinFrequency(), newm); + + return true; +} + + +bool V4LRadio::setScanStep(float s) +{ + float old = m_scanStep; + m_scanStep = s; + + if (old != s) notifyScanStepChanged(m_scanStep); + return true; +} + + +float V4LRadio::getFrequency() const +{ + return m_currentStation.frequency(); +} + + +float V4LRadio::getMinFrequency() const +{ + return m_minFrequency ? m_minFrequency : getMinDeviceFrequency(); +} + + +float V4LRadio::getMaxFrequency() const +{ + return m_maxFrequency ? m_maxFrequency : getMaxDeviceFrequency(); +} + + +float V4LRadio::getMinDeviceFrequency() const +{ + if (!m_tunercache.valid) + readTunerInfo(); + + return m_tunercache.minF; +} + + +float V4LRadio::getMaxDeviceFrequency() const +{ + if (!m_tunercache.valid) + readTunerInfo(); + + return m_tunercache.maxF; +} + + +float V4LRadio::getScanStep() const +{ + return m_scanStep; +} + + + +// IV4LCfg methods + +bool V4LRadio::setRadioDevice(const QString &s) +{ + if (m_radioDev != s) { + bool p = isPowerOn(); + powerOff(); + m_radioDev = s; + + m_caps = readV4LCaps(m_radioDev); + notifyRadioDeviceChanged(m_radioDev); + notifyDescriptionChanged(m_caps.description); + notifyCapabilitiesChanged(m_caps); + setPower(p); + } + return true; +} + + +bool V4LRadio::setPlaybackMixer(const QString &soundStreamClientID, const QString &ch) +{ + bool change = m_PlaybackMixerID != soundStreamClientID || m_PlaybackMixerChannel != ch; + m_PlaybackMixerID = soundStreamClientID; + m_PlaybackMixerChannel = ch; + + + if (isPowerOn()) { + queryPlaybackVolume(m_SoundStreamID, m_defaultPlaybackVolume); + sendStopPlayback(m_SoundStreamID); + sendReleasePlayback(m_SoundStreamID); + } + + ISoundStreamClient *playback_mixer = NULL; + searchMixers(&playback_mixer, NULL); + if (playback_mixer) + playback_mixer->preparePlayback(m_SoundStreamID, m_PlaybackMixerChannel, m_ActivePlayback, false); + + if (isPowerOn()) { + sendStartPlayback(m_SoundStreamID); + sendPlaybackVolume(m_SoundStreamID, m_defaultPlaybackVolume); + if (m_ActivePlayback) { + SoundFormat sf; + sendStartCaptureWithFormat(m_SoundStreamID, sf, sf); + } + } + + if (change) + notifyPlaybackMixerChanged(soundStreamClientID, ch); + + return true; +} + + +bool V4LRadio::setCaptureMixer(const QString &soundStreamClientID, const QString &ch) +{ + bool change = m_PlaybackMixerID != soundStreamClientID || m_PlaybackMixerChannel != ch; + m_CaptureMixerID = soundStreamClientID; + m_CaptureMixerChannel = ch; + + bool r = false; + SoundFormat sf; + queryIsCaptureRunning(m_SoundStreamID, r, sf); + + float v = 0; + if (isPowerOn() && r) { + queryCaptureVolume(m_SoundStreamID, v); + sendStopCapture(m_SoundStreamID); + sendReleaseCapture(m_SoundStreamID); + } + + ISoundStreamClient *capture_mixer = NULL; + searchMixers(NULL, &capture_mixer); + if (capture_mixer) + capture_mixer->prepareCapture(m_SoundStreamID, m_CaptureMixerChannel); + + if (isPowerOn() && r) { + sendStartCaptureWithFormat(m_SoundStreamID, sf, sf); + sendCaptureVolume(m_SoundStreamID, v); + } + + if (change) + notifyCaptureMixerChanged(soundStreamClientID, ch); + + return true; +} + + +V4LCaps V4LRadio::getCapabilities(QString dev) const +{ + if (dev.isNull()) { + return m_caps; + } else { + return readV4LCaps(dev); + } +} + + +bool V4LRadio::setActivePlayback(bool a) +{ + if (a == m_ActivePlayback) + return true; + + + if (isPowerOn()) { + queryPlaybackVolume(m_SoundStreamID, m_defaultPlaybackVolume); + sendStopPlayback(m_SoundStreamID); + sendReleasePlayback(m_SoundStreamID); + if (m_ActivePlayback) { + sendStopCapture(m_SoundStreamID); + } + } + + m_ActivePlayback = a; + + ISoundStreamClient *playback_mixer = NULL; + searchMixers(&playback_mixer, NULL); + if (playback_mixer) + playback_mixer->preparePlayback(m_SoundStreamID, m_PlaybackMixerChannel, m_ActivePlayback, false); + + if (isPowerOn()) { + sendStartPlayback(m_SoundStreamID); + sendPlaybackVolume(m_SoundStreamID, m_defaultPlaybackVolume); + if (m_ActivePlayback) { + SoundFormat sf; + sendStartCaptureWithFormat(m_SoundStreamID, sf, sf); + } + } + + // FIXME: restart playback/capture + notifyActivePlaybackChanged(m_ActivePlayback); + + return true; +} + +bool V4LRadio::setMuteOnPowerOff(bool a) +{ + if (a != m_MuteOnPowerOff) { + m_MuteOnPowerOff = a; + notifyMuteOnPowerOffChanged(m_MuteOnPowerOff); + } + return true; +} + +bool V4LRadio::setVolumeZeroOnPowerOff(bool a) +{ + if (a != m_VolumeZeroOnPowerOff) { + m_VolumeZeroOnPowerOff = a; + notifyVolumeZeroOnPowerOffChanged(m_VolumeZeroOnPowerOff); + } + return true; +} + +// PluginBase methods + +void V4LRadio::saveState (KConfig *config) const +{ + config->setGroup(QString("v4lradio-") + name()); + + config->writeEntry("RadioDev", m_radioDev); + + config->writeEntry("PlaybackMixerID", m_PlaybackMixerID); + config->writeEntry("PlaybackMixerChannel", m_PlaybackMixerChannel); + config->writeEntry("CaptureMixerID", m_CaptureMixerID); + config->writeEntry("CaptureMixerChannel", m_CaptureMixerChannel); + + config->writeEntry("fMinOverride", m_minFrequency); + config->writeEntry("fMaxOverride", m_maxFrequency); + config->writeEntry("fLastDevMin", m_lastMinDevFrequency); + config->writeEntry("fLastDevMax", m_lastMaxDevFrequency); + + config->writeEntry("defaultPlaybackVolume", m_defaultPlaybackVolume); + + config->writeEntry("signalMinQuality", m_minQuality); + + config->writeEntry("scanStep", m_scanStep); + + config->writeEntry("Frequency", m_currentStation.frequency()); + config->writeEntry("Treble", m_treble); + config->writeEntry("Bass", m_bass); + config->writeEntry("Balance", m_balance); + config->writeEntry("DeviceVolume", m_deviceVolume); + + config->writeEntry("PowerOn", isPowerOn()); + config->writeEntry("UseOldV4L2Calls", m_useOldV4L2Calls); + + config->writeEntry("ActivePlayback", m_ActivePlayback); + config->writeEntry("MuteOnPowerOff", m_MuteOnPowerOff); + config->writeEntry("VolumeZeroOnPowerOff", m_VolumeZeroOnPowerOff); +} + + +void V4LRadio::restoreState (KConfig *config) +{ + BlockProfiler p("V4LRadio::restoreState"); + + config->setGroup(QString("v4lradio-") + name()); + + QString base_devname = "/dev/radio"; + + QStringList testlist (base_devname ); + for (int i = 0; i < 9; ++i) + testlist.append(base_devname + QString::number(i)); + + QString found_devname(QString::null); + for (QValueListConstIterator<QString> it = testlist.begin(); it != testlist.end(); ++it) { + QFile f(*it); + if (f.exists()) { + QFileInfo info(f); + if (info.isReadable() && info.isWritable()) { + found_devname = *it; + break; + } + else { + if (found_devname.isNull()) + found_devname = *it; + logWarning(i18n("Device %1 does exist but is not readable/writable. Please check device permissions.").arg(*it)); + } + } + } + + QString default_devname = found_devname.isNull() ? base_devname : found_devname; + + QString devname = config->readEntry ("RadioDev", default_devname); + + if (found_devname.isNull() && devname == default_devname) { + logError(i18n("Could not find an accessible v4l(2) radio device.")); + } + + setRadioDevice(devname); + + QString PlaybackMixerID = config->readEntry ("PlaybackMixerID", QString::null); + QString PlaybackMixerChannel = config->readEntry ("PlaybackMixerChannel", "Line"); + + QString CaptureMixerID = config->readEntry ("CaptureMixerID", QString::null); + QString CaptureMixerChannel = config->readEntry ("CaptureMixerChannel", "Line"); + + m_ActivePlayback = config->readBoolEntry("ActivePlayback", false); + m_MuteOnPowerOff = config->readBoolEntry("MuteOnPowerOff", false); + m_VolumeZeroOnPowerOff = config->readBoolEntry("VolumeZeroOnPowerOff", false); + + m_lastMinDevFrequency = config->readDoubleNumEntry ("fLastDevMin", 65.0); + m_lastMaxDevFrequency = config->readDoubleNumEntry ("fLastDevMax", 108.0); + m_minFrequency = config->readDoubleNumEntry ("fMinOverride", m_lastMinDevFrequency); + m_maxFrequency = config->readDoubleNumEntry ("fMaxOverride", m_lastMaxDevFrequency); + + m_minQuality = config->readDoubleNumEntry ("signalMinQuality", 0.75); + m_scanStep = config->readDoubleNumEntry ("scanStep", 0.05); + m_defaultPlaybackVolume = config->readDoubleNumEntry ("defaultPlaybackVolume", 0.5); + + setPlaybackMixer(PlaybackMixerID, PlaybackMixerChannel); + setCaptureMixer (CaptureMixerID, CaptureMixerChannel); + notifyDeviceMinMaxFrequencyChanged(m_lastMinDevFrequency, m_lastMaxDevFrequency); + notifyMinMaxFrequencyChanged(m_minFrequency, m_maxFrequency); + notifySignalMinQualityChanged(m_SoundStreamID, m_minQuality); + notifyScanStepChanged(m_scanStep); + notifyActivePlaybackChanged(m_ActivePlayback); + notifyMuteOnPowerOffChanged(m_MuteOnPowerOff); + notifyVolumeZeroOnPowerOffChanged(m_VolumeZeroOnPowerOff); + + BlockProfiler p2("V4LRadio::restoreState2"); + + setFrequency(config->readDoubleNumEntry("Frequency", 88)); + m_restorePowerOn = config->readBoolEntry ("PowerOn", false); + + BlockProfiler p3("V4LRadio::restoreState3"); + + setTreble (m_SoundStreamID, config->readDoubleNumEntry("Treble", 0.5)); + setBass (m_SoundStreamID, config->readDoubleNumEntry("Bass", 0.5)); + setBalance (m_SoundStreamID, config->readDoubleNumEntry("Balance", 0.0)); + setDeviceVolume( config->readDoubleNumEntry("DeviceVolume", 0.9)); + + m_useOldV4L2Calls = config->readBoolEntry("UseOldV4L2Calls", true); + + if (isPowerOff()) + notifyPlaybackVolumeChanged(m_SoundStreamID, m_defaultPlaybackVolume); +} + +void V4LRadio::startPlugin() +{ + PluginBase::startPlugin(); + setPower(m_restorePowerOn); +} + +ConfigPageInfo V4LRadio::createConfigurationPage() +{ + V4LRadioConfiguration *v4lconf = new V4LRadioConfiguration(NULL, m_SoundStreamID); + connectI(v4lconf); + return ConfigPageInfo (v4lconf, + i18n("V4L Radio"), + i18n("V4L Radio Options"), + "package_utilities"); +} + + +AboutPageInfo V4LRadio::createAboutPage() +{ + KAboutData aboutData("kradio", + NULL, + NULL, + I18N_NOOP("V4L/V4L2 Plugin for KRadio." + "<P>" + "Provides Support for V4L/V4L2 based Radio Cards" + "<P>"), + 0, + //KAboutData::License_GPL, + "(c) 2002-2005 Martin Witte, Klas Kalass", + 0, + "http://sourceforge.net/projects/kradio", + 0); + aboutData.addAuthor("Martin Witte", "", "witte@kawo1.rwth-aachen.de"); + aboutData.addAuthor("Klas Kalass", "", "klas.kalass@gmx.de"); + + return AboutPageInfo( + new KRadioAboutWidget(aboutData, KRadioAboutWidget::AbtTabbed), + i18n("V4L/V4L2"), + i18n("V4L/V4L2 Plugin"), + "package_utilities" + ); +} + +//////////////////////////////////////// +// anything else + +void V4LRadio::radio_init() +{ + if (isSeekRunning()) + stopSeek(); + + m_caps = readV4LCaps(m_radioDev); + notifyCapabilitiesChanged(m_caps); + notifyDescriptionChanged(m_caps.description); + +/* m_mixer_fd = open(m_mixerDev, O_RDONLY); + if (m_mixer_fd < 0) { + radio_done(); + + logError("V4LRadio::radio_init: " + + i18n("Cannot open mixer device %1").arg(m_mixerDev)); + return; + } +*/ + m_radio_fd = open(m_radioDev.ascii(), O_RDONLY); + if (m_radio_fd < 0) { + radio_done(); + + logError("V4LRadio::radio_init: " + + i18n("Cannot open radio device %1").arg(m_radioDev)); + return; + } + + readTunerInfo(); + writeAudioInfo(); // set tuner-audio config as used last time + readAudioInfo(); // reread tuner-audio and read-only flags (e.g. stereo) + + // restore frequency + float old = getFrequency(); + m_currentStation.setFrequency(0); + setFrequency(old); + + // read volume level from mixer + // FIXME: do we still need this +/* float v = 0; + getVolume(m_SoundStreamID, v) + setVolume (m_SoundStreamID, v);*/ +} + + +void V4LRadio::radio_done() +{ + if (isSeekRunning()) + stopSeek(); + + if (m_radio_fd >= 0) close (m_radio_fd); +// if (m_mixer_fd >= 0) close (m_mixer_fd); + + m_radio_fd = -1; +// m_mixer_fd = -1; +} + + + + + +#define CAPS_NAME_LEN 127 +V4LCaps V4LRadio::readV4LCaps(const QString &device) const +{ + char buffer[CAPS_NAME_LEN+1]; + int r; + int fd; + + V4LCaps c; + c.description = device; + + fd = open(device.ascii(), O_RDONLY); + + if (fd < 0) { + logError("V4LRadio::readV4LCaps: " + + i18n("cannot open %1").arg(device)); + return c; + } + + video_capability caps; + r = ioctl(fd, VIDIOCGCAP, &caps); + if (r == 0) { + c.version = 1; + + size_t l = sizeof(caps.name); + l = l < CAPS_NAME_LEN ? l : CAPS_NAME_LEN; + memcpy(buffer, caps.name, l); + buffer[l] = 0; + c.description = buffer; + + c.hasMute = false; + c.unsetVolume(); + c.unsetTreble(); + c.unsetBass(); + c.unsetBalance(); + + video_audio audiocaps; + if (0 == ioctl(fd, VIDIOCGAUDIO, &audiocaps)) { + logDebug("V4LRadio::readV4LCaps: " + + i18n("audio caps = %1").arg(QString().setNum(audiocaps.flags))); + if ((audiocaps.flags & VIDEO_AUDIO_MUTABLE) != 0) + c.hasMute = true; + if ((audiocaps.flags & VIDEO_AUDIO_VOLUME) != 0) + c.setVolume (0, 65535); + if ((audiocaps.flags & VIDEO_AUDIO_TREBLE) != 0) + c.setTreble (0, 65535); + if ((audiocaps.flags & VIDEO_AUDIO_BASS) != 0) + c.setBass (0, 65535); + // at least my driver has support for balance, but the bit is not set ... + c.setBalance(0, 65535); + } + } else { + logError("V4LRadio::readV4LCaps: " + + i18n("error reading V4L1 caps")); + } + +#ifdef HAVE_V4L2 + v4l2_capability caps2; + r = ioctl(fd, VIDIOC_QUERYCAP, &caps2); + if (r == 0) { + c.version = 2; + + logDebug(i18n("V4L2 - Version: %1").arg(QString().sprintf("%08X", caps2.version))); + + size_t l = sizeof(caps.name); + l = l < CAPS_NAME_LEN ? l : CAPS_NAME_LEN; + memcpy(buffer, caps.name, l); + buffer[l] = 0; + // c.description = buffer; + + v4l2_queryctrl ctrl; + + c.hasMute = false; + c.unsetVolume(); + c.unsetTreble(); + c.unsetBass(); + c.unsetBalance(); + + ctrl.id = V4L2_CID_AUDIO_MUTE; + if (0 == ioctl(fd, VIDIOC_QUERYCTRL, &ctrl)) + c.hasMute = !(ctrl.flags & V4L2_CTRL_FLAG_DISABLED); + else + logError(i18n("V4L2: Querying mute control failed")); + + ctrl.id = V4L2_CID_AUDIO_VOLUME; + if (0 == ioctl(fd, VIDIOC_QUERYCTRL, &ctrl)) { + if (!(ctrl.flags & V4L2_CTRL_FLAG_DISABLED)) + c.setVolume(ctrl.minimum, ctrl.maximum); + } else { + logError(i18n("V4L2: Querying volume control failed")); + } + + ctrl.id = V4L2_CID_AUDIO_TREBLE; + if (0 == ioctl(fd, VIDIOC_QUERYCTRL, &ctrl)) { + if (!(ctrl.flags & V4L2_CTRL_FLAG_DISABLED)) + c.setTreble(ctrl.minimum, ctrl.maximum); + } else { + logError(i18n("V4L2: Querying treble control failed")); + } + + ctrl.id = V4L2_CID_AUDIO_BASS; + if (0 == ioctl(fd, VIDIOC_QUERYCTRL, &ctrl)) { + if (!(ctrl.flags & V4L2_CTRL_FLAG_DISABLED)) + c.setBass(ctrl.minimum, c.maxBass = ctrl.maximum); + } else { + logError(i18n("V4L2: Querying bass control failed")); + } + + ctrl.id = V4L2_CID_AUDIO_BALANCE; + if (0 == ioctl(fd, VIDIOC_QUERYCTRL, &ctrl)) { + if (!(ctrl.flags & V4L2_CTRL_FLAG_DISABLED)) + c.setBalance(ctrl.minimum, ctrl.maximum); + } else { + logError(i18n("V4L2: Querying balance control failed")); + } + + } else { + logWarning(i18n("V4LRadio::readV4LCaps: Reading V4L2 caps failed")); + } +#endif + if (c.version > 0) { + logInfo(i18n("V4L %1 detected").arg(c.version)); + } else { + logError(i18n("V4L not detected")); + } + + logInfo(c.hasMute ? i18n("Radio is mutable") : i18n("Radio is not mutable")); + logInfo(c.hasVolume ? i18n("Radio has Volume Control") : i18n("Radio has no Volume Control")); + logInfo(c.hasBass ? i18n("Radio has Bass Control") : i18n("Radio has no Bass Control")); + logInfo(c.hasTreble ? i18n("Radio has Treble Control") : i18n("Radio has no Treble Control")); + + close(fd); + return c; +} + + +bool V4LRadio::readTunerInfo() const +{ + if (m_blockReadTuner) return true; + + float oldq = m_signalQuality; + float oldminf = m_tunercache.minF; + float oldmaxf = m_tunercache.maxF; + + if (!m_tunercache.valid) { + m_tunercache.minF = m_lastMinDevFrequency; + m_tunercache.maxF = m_lastMaxDevFrequency; + m_tunercache.deltaF = 1.0/16.0; + m_tunercache.valid = true; + } + + int r = 0; + if (isPowerOn()) { + + // v4l1 + if (m_caps.version == 1) { + + r = ioctl(m_radio_fd, VIDIOCGTUNER, m_tuner); + + if (r == 0) { + if ((m_tuner->flags & VIDEO_TUNER_LOW) != 0) + m_tunercache.deltaF = 1.0 / 16000.0; + m_tunercache.minF = float(m_tuner->rangelow) * m_tunercache.deltaF; + m_tunercache.maxF = float(m_tuner->rangehigh) * m_tunercache.deltaF; + m_tunercache.valid = true; + m_signalQuality = float(m_tuner->signal) / 32767.0; + + } + } +#ifdef HAVE_V4L2 + // v4l2 + else if (m_caps.version == 2) { + + r = ioctl(m_radio_fd, VIDIOC_G_TUNER, m_tuner2); + + if (r == 0) { + if ((m_tuner2->capability & V4L2_TUNER_CAP_LOW) != 0) + m_tunercache.deltaF = 1.0 / 16000.0; + m_tunercache.minF = float(m_tuner2->rangelow) * m_tunercache.deltaF; + m_tunercache.maxF = float(m_tuner2->rangehigh) * m_tunercache.deltaF; + m_tunercache.valid = true; + m_signalQuality = float(m_tuner2->signal) / 32767.0; + } + } +#endif + else { + logError("V4LRadio::readTunerInfo: " + + i18n("don't known how to handle V4L-version %1") + .arg(QString().setNum(m_caps.version))); + } + + if (r != 0) { + m_signalQuality = 0; + logError("V4LRadio::readTunerInfo: " + + i18n("cannot get tuner info (error %1)").arg(QString().setNum(r))); + } + } else { + m_signalQuality = 0; + } + + // prevent loops, if noticeXYZ-method is reading my state + m_blockReadTuner = true; + + if (oldminf != m_tunercache.minF || oldmaxf != m_tunercache.maxF) + notifyDeviceMinMaxFrequencyChanged(m_tunercache.minF, m_tunercache.maxF); + m_lastMinDevFrequency = m_tunercache.minF; + m_lastMaxDevFrequency = m_tunercache.maxF; + + if ( ! m_minFrequency && (oldminf != m_tunercache.minF) + || ! m_maxFrequency && (oldmaxf != m_tunercache.maxF)) + notifyMinMaxFrequencyChanged(getMinFrequency(), getMaxFrequency()); + + + if (m_signalQuality != oldq) + notifySignalQualityChanged(m_SoundStreamID, m_signalQuality); + if ( (m_signalQuality >= m_minQuality) != (oldq >= m_minQuality)) + notifySignalQualityBoolChanged(m_SoundStreamID, m_signalQuality > m_minQuality); + + m_blockReadTuner = false; + + return true; +} + + + +#define V4L2_S_CTRL(what,val) \ + { ctl.value = (val); \ + ctl.id = (what); \ + /* Problem: Current V4L2 development has changed the IOCTL-IDs for VIDIOC_S_CTRL */ \ + /* => we must du "try and error" to figure out what version we should use */ \ + r = ioctl (m_radio_fd, m_useOldV4L2Calls ? VIDIOC_S_CTRL_OLD : VIDIOC_S_CTRL, &ctl); \ + /* in case this did not work, try the other version of the call */ \ + if (r) { \ + r = ioctl (m_radio_fd, !m_useOldV4L2Calls ? VIDIOC_S_CTRL_OLD : VIDIOC_S_CTRL, &ctl); \ + if (!r) m_useOldV4L2Calls = !m_useOldV4L2Calls; \ + } \ + x = x ? x : r; \ + if (r) \ + logError(i18n("error setting %1: %2").arg(#what).arg(QString().setNum(r))); \ + } + +#define V4L2_G_CTRL(what) \ + { ctl.id = (what); \ + r = ioctl (m_radio_fd, VIDIOC_G_CTRL, &ctl); \ + x = x ? x : r; \ + if (r) \ + logError(i18n("error reading %1: %2").arg(#what).arg(QString().setNum(r))); \ + } + + +bool V4LRadio::updateAudioInfo(bool write) const +{ + if (m_blockReadAudio && !write) + return true; + + bool oldStereo = m_stereo; + bool oldMute = m_muted; + int iOldDeviceVolume = m_caps.intGetVolume (m_deviceVolume); + int iOldTreble = m_caps.intGetTreble (m_treble); + int iOldBass = m_caps.intGetBass (m_bass); + int iOldBalance = m_caps.intGetBalance(m_balance); + + if (isPowerOn()) { + int r = 0; + if (m_caps.version == 1) { + m_audio->audio = 0; + if (m_muted) m_audio->flags |= VIDEO_AUDIO_MUTE; + else m_audio->flags &= ~VIDEO_AUDIO_MUTE; + + m_audio->volume = m_caps.intGetVolume (m_deviceVolume); + m_audio->treble = m_caps.intGetTreble (m_treble); + m_audio->bass = m_caps.intGetBass (m_bass); + m_audio->balance = m_caps.intGetBalance(m_balance); + + r = ioctl(m_radio_fd, write ? VIDIOCSAUDIO : VIDIOCGAUDIO, m_audio); + + m_stereo = (r == 0) && ((m_audio->mode & VIDEO_SOUND_STEREO) != 0); + + m_muted = m_caps.hasMute && + ((r != 0) || ((m_audio->flags & VIDEO_AUDIO_MUTE) != 0)); + + /* Some drivers seem to set volumes to zero if they are muted. + Thus we do not reload them if radio is muted */ + if (!m_muted && !write) { + m_deviceVolume = m_caps.hasVolume && !r ? m_caps.floatGetVolume (m_audio->volume) : 1; + m_treble = m_caps.hasTreble && !r ? m_caps.floatGetTreble (m_audio->treble) : 1; + m_bass = m_caps.hasBass && !r ? m_caps.floatGetBass (m_audio->bass) : 1; + m_balance = m_caps.hasBalance && !r ? m_caps.floatGetBalance(m_audio->balance) : 0; + } + } +#ifdef HAVE_V4L2 + else if (m_caps.version == 2) { + v4l2_control ctl; + int x = 0; // x stores first ioctl error + if (write) { + if (m_caps.hasMute) + V4L2_S_CTRL(V4L2_CID_AUDIO_MUTE, m_muted); + if (m_caps.hasTreble) + V4L2_S_CTRL(V4L2_CID_AUDIO_TREBLE, m_caps.intGetTreble(m_treble)); + if (m_caps.hasBass) + V4L2_S_CTRL(V4L2_CID_AUDIO_BASS, m_caps.intGetBass(m_bass)); + if (m_caps.hasBalance) + V4L2_S_CTRL(V4L2_CID_AUDIO_BALANCE, m_caps.intGetBalance(m_balance)); + if (m_caps.hasVolume) + V4L2_S_CTRL(V4L2_CID_AUDIO_VOLUME, m_caps.intGetVolume(m_deviceVolume)); + } else { + if (m_caps.hasMute) + V4L2_G_CTRL(V4L2_CID_AUDIO_MUTE); + m_muted = m_caps.hasMute && ((r != 0) || ctl.value); + + /* Some drivers seem to set volumes to zero if they are muted. + Thus we do not reload them if radio is muted */ + if (!m_muted) { + if (m_caps.hasVolume) + V4L2_G_CTRL(V4L2_CID_AUDIO_VOLUME); + m_deviceVolume = m_caps.hasVolume && !r ? m_caps.floatGetVolume (ctl.value) : 1; + if (m_caps.hasTreble) + V4L2_G_CTRL(V4L2_CID_AUDIO_TREBLE); + m_treble = m_caps.hasTreble && !r ? m_caps.floatGetTreble (ctl.value) : 1; + if (m_caps.hasBass) + V4L2_G_CTRL(V4L2_CID_AUDIO_BASS); + m_bass = m_caps.hasBass && !r ? m_caps.floatGetBass (ctl.value) : 1; + if (m_caps.hasBalance) + V4L2_G_CTRL(V4L2_CID_AUDIO_BALANCE); + m_balance = m_caps.hasBalance&& !r ? m_caps.floatGetBalance(ctl.value) : 0; + } + + r = ioctl (m_radio_fd, VIDIOC_G_TUNER, m_tuner2); + m_stereo = (r == 0) && ((m_tuner2->rxsubchans & V4L2_TUNER_SUB_STEREO) != 0); + x = x ? x : r; + } + r = x; // store first error back to r, used below for error message + } +#endif + else { + logError("V4LRadio::updateAudioInfo: " + + i18n("don't known how to handle V4L-version %1") + .arg(QString().setNum(m_caps.version))); + } + + if (r) { + logError("V4LRadio::updateAudioInfo: " + + i18n("error updating radio audio info (%1): %2") + .arg(write ? i18n("write") : i18n("read")) + .arg(QString().setNum(r))); + return false; + } + } + + // prevent loops, if noticeXYZ-method is reading my state + bool oldBlock = m_blockReadAudio; + m_blockReadAudio = true; + + // send notifications + + if (oldStereo != m_stereo) + notifyStereoChanged(m_SoundStreamID, m_stereo); + if (oldMute != m_muted) + notifyMuted(m_SoundStreamID, m_muted); + if (iOldDeviceVolume != m_caps.intGetVolume(m_deviceVolume)) + notifyDeviceVolumeChanged(m_deviceVolume); + if (iOldTreble != m_caps.intGetTreble(m_treble)) + notifyTrebleChanged(m_SoundStreamID, m_treble); + if (iOldBass != m_caps.intGetBass(m_bass)) + notifyBassChanged(m_SoundStreamID, m_bass); + if (iOldBalance != m_caps.intGetBalance(m_balance)) + notifyBalanceChanged(m_SoundStreamID, m_balance); + + m_blockReadAudio = oldBlock; + + return isPowerOn(); +} + + + + +void V4LRadio::poll() +{ + readTunerInfo(); + readAudioInfo(); +} + + +bool V4LRadio::setPlaybackVolume(SoundStreamID id, float volume) +{ + if (isPowerOff() && id == m_SoundStreamID) { + m_defaultPlaybackVolume = min(max(volume, 0.0), 1.0); + return true; + } else { + return false; + } +} + +bool V4LRadio::getPlaybackVolume(SoundStreamID id, float &volume) const +{ + if (isPowerOff() && id == m_SoundStreamID) { + volume = m_defaultPlaybackVolume; + return true; + } else { + return false; + } +} + + + +bool V4LRadio::getSoundStreamDescription(SoundStreamID id, QString &descr) const +{ + if (id == m_SoundStreamID) { + descr = name() + " - " + m_currentStation.name(); + return true; + } + else { + return false; + } +} + + +bool V4LRadio::getSoundStreamRadioStation(SoundStreamID id, const RadioStation *&rs) const +{ + if (id == m_SoundStreamID) { + rs = &m_currentStation; + return true; + } + else { + return false; + } +} + + +bool V4LRadio::enumerateSoundStreams(QMap<QString, SoundStreamID> &list) const +{ + if (m_SoundStreamID.isValid()) { + QString tmp = QString::null; + getSoundStreamDescription(m_SoundStreamID, tmp); + list[tmp] = m_SoundStreamID; + return true; + } + return false; +} + + +// bool V4LRadio::stopCapture(SoundStreamID id) +// { +// if (id.isValid() && id == m_SoundStreamID && m_ActivePlayback) { +// sendStopPlayback(id); +// return true; +// } +// return false; +// } + +#include "v4lradio.moc" diff --git a/kradio3/plugins/v4lradio/v4lradio.h b/kradio3/plugins/v4lradio/v4lradio.h new file mode 100644 index 0000000..4b86cb5 --- /dev/null +++ b/kradio3/plugins/v4lradio/v4lradio.h @@ -0,0 +1,265 @@ +/*************************************************************************** + v4lradio.h - description + ------------------- + begin : Jan 2002 + copyright : (C) 2002-2005 Ernst Martin Witte, Klas Kalass + email : witte@kawo1.rwth-aachen.de, klas@kde.org + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KRADIO_V4LRADIO_H +#define KRADIO_V4LRADIO_H + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <qtimer.h> + +#include "../../src/include/radiodevice_interfaces.h" +#include "../../src/include/plugins.h" +#include "../../src/include/frequencyradiostation.h" +#include "../../src/include/frequencyseekhelper.h" +#include "../../src/include/soundstreamclient_interfaces.h" +#include "v4lcfg_interfaces.h" + + +struct video_tuner; +struct video_audio; +#ifdef HAVE_V4L2 +struct v4l2_tuner; +#endif + +class V4LRadio : public QObject, + public PluginBase, + public IRadioDevice, +// public IRadioSound, + public ISeekRadio, + public IFrequencyRadio, + public ISoundStreamClient, + public IV4LCfg +{ +Q_OBJECT +public: + V4LRadio (const QString &name); + virtual ~V4LRadio (); + + virtual bool connectI (Interface *); + virtual bool disconnectI (Interface *); + + virtual QString pluginClassName() const { return "V4LRadio"; } + + virtual const QString &name() const { return PluginBase::name(); } + virtual QString &name() { return PluginBase::name(); } + + // PluginBase + +public: + virtual void saveState (KConfig *) const; + virtual void restoreState (KConfig *); + virtual void startPlugin(); + + virtual ConfigPageInfo createConfigurationPage(); + virtual AboutPageInfo createAboutPage(); + + // IRadioDevice methods + +RECEIVERS: + virtual bool setPower(bool p); + virtual bool powerOn(); + virtual bool powerOff(); + virtual bool activateStation(const RadioStation &rs); + +ANSWERS: + virtual bool isPowerOn() const; + virtual bool isPowerOff() const; + virtual SoundStreamID getSoundStreamID() const; + virtual const RadioStation & getCurrentStation() const; + virtual const QString & getDescription() const; + virtual SoundStreamID getCurrentSoundStreamID() const; + + + // ISeekRadio + +RECEIVERS: + virtual bool toBeginning(); + virtual bool toEnd(); + virtual bool startSeek (bool up); + virtual bool startSeekUp(); + virtual bool startSeekDown(); + virtual bool stopSeek(); + +ANSWERS: + virtual bool isSeekRunning() const; + virtual bool isSeekUpRunning() const; + virtual bool isSeekDownRunning() const; + virtual float getProgress () const; + + + // IFrequencyRadio + +RECEIVERS: + virtual bool setFrequency(float f); + virtual bool setMinFrequency(float mf); + virtual bool setMaxFrequency(float mf); + virtual bool setScanStep(float s); + +ANSWERS: + virtual float getFrequency() const; + virtual float getMinFrequency() const; + virtual float getMinDeviceFrequency() const; + virtual float getMaxFrequency() const; + virtual float getMaxDeviceFrequency() const; + virtual float getScanStep() const; + + + // ISoundStreamClient: mixer functions + + +RECEIVERS: + void noticeConnectedI (ISoundStreamServer *s, bool pointer_valid); + void noticeConnectedSoundClient(ISoundStreamClient::thisInterface *i, bool pointer_valid); + + bool setTreble (SoundStreamID, float v); + bool setBass (SoundStreamID, float v); + bool setBalance (SoundStreamID, float v); + bool mute (SoundStreamID, bool mute = true); + bool unmute (SoundStreamID, bool unmute = true); + bool setSignalMinQuality(SoundStreamID, float q); + bool setStereo(SoundStreamID, bool s); + + bool getTreble(SoundStreamID, float &v) const; + bool getBass (SoundStreamID, float &v) const; + bool getBalance (SoundStreamID, float &b) const; + bool getSignalQuality(SoundStreamID, float &q) const; + bool getSignalMinQuality(SoundStreamID, float &q) const; + bool hasGoodQuality(SoundStreamID, bool &) const; + bool isStereo(SoundStreamID, bool &s) const; + bool isMuted(SoundStreamID, bool &m) const; + + // ISoundStreamClient: generic stream handling (broadcasts) + +RECEIVERS: + + bool getSoundStreamDescription(SoundStreamID id, QString &descr) const; + bool getSoundStreamRadioStation(SoundStreamID id, const RadioStation *&rs) const; + bool enumerateSoundStreams(QMap<QString, SoundStreamID> &list) const; + +// bool stopCapture(SoundStreamID id); // if active playback also call stopPlayback + + + // IV4LCfg +RECEIVERS: + bool setRadioDevice (const QString &s); + bool setPlaybackMixer(const QString &soundStreamClientID, const QString &ch); + bool setCaptureMixer (const QString &soundStreamClientID, const QString &ch); + bool setDeviceVolume (float v); + bool setActivePlayback(bool a); + bool setMuteOnPowerOff(bool a); + bool setVolumeZeroOnPowerOff(bool a); + + // if the radio is powered off, we will handle the volume by changing m_defaultPlaybackVolume + bool setPlaybackVolume(SoundStreamID id, float volume); + bool getPlaybackVolume(SoundStreamID id, float &volume) const; + +ANSWERS: + const QString &getRadioDevice () const { return m_radioDev; } + const QString &getPlaybackMixerID () const { return m_PlaybackMixerID; } + const QString &getCaptureMixerID () const { return m_CaptureMixerID; } + const QString &getPlaybackMixerChannel() const { return m_PlaybackMixerChannel; } + const QString &getCaptureMixerChannel () const { return m_CaptureMixerChannel; } + float getDeviceVolume () const; + V4LCaps getCapabilities(QString dev = QString::null) const; + + bool getActivePlayback() const { return m_ActivePlayback; } + bool getMuteOnPowerOff() const { return m_MuteOnPowerOff; } + bool getVolumeZeroOnPowerOff() const { return m_VolumeZeroOnPowerOff; } + + // anything else + +protected slots: + void poll(); + +protected: + V4LCaps readV4LCaps(const QString &device) const; + void radio_init(); + void radio_done(); + + bool readTunerInfo() const; + bool updateAudioInfo(bool write) const; + bool readAudioInfo() const { return updateAudioInfo(false); } + bool writeAudioInfo() const { return updateAudioInfo(true); } + + void searchMixers(ISoundStreamClient **playback_mixer, ISoundStreamClient **capture_mixer); + +protected: + + FrequencyRadioStation m_currentStation; + mutable float m_treble; + mutable float m_bass; + mutable float m_balance; + mutable float m_deviceVolume; + mutable bool m_muted; + mutable float m_signalQuality; + mutable bool m_stereo; + + float m_minQuality; + float m_minFrequency; + float m_maxFrequency; + mutable float m_lastMinDevFrequency; + mutable float m_lastMaxDevFrequency; + + float m_defaultPlaybackVolume; + + FrequencySeekHelper *m_seekHelper; + float m_scanStep; + + V4LCaps m_caps; + QString m_radioDev; + int m_radio_fd; + + mutable bool m_useOldV4L2Calls; + + + mutable struct video_audio *m_audio; + mutable struct video_tuner *m_tuner; +#ifdef HAVE_V4L2 + mutable struct v4l2_tuner *m_tuner2; +#endif + + QTimer m_pollTimer; + + struct TunerCache { + bool valid; + float deltaF; + float minF, maxF; + TunerCache() { valid = false; deltaF = minF = maxF = 0; } + }; + mutable struct TunerCache m_tunercache; + + + mutable bool m_blockReadTuner, + m_blockReadAudio; + + SoundStreamID m_SoundStreamID; + QString m_PlaybackMixerID; + QString m_CaptureMixerID; + QString m_PlaybackMixerChannel; + QString m_CaptureMixerChannel; + + bool m_ActivePlayback; + bool m_MuteOnPowerOff; + bool m_VolumeZeroOnPowerOff; + + bool m_restorePowerOn; +}; + +#endif |