gnomeradio r194 - in trunk: . data src



Author: mfcn
Date: Sun Apr 13 15:30:58 2008
New Revision: 194
URL: http://svn.gnome.org/viewvc/gnomeradio?rev=194&view=rev

Log:
	* data/gnomeradio.schemas.in:
	* src/Makefile.am:
	* src/gui.c (initial_frequency_scan_cb), (initial_frequency_scan),
	(start_radio), (redraw_status_window), (adj_value_changed_cb):
	* src/gui.h:
	* src/prefs.c (save_settings), (load_settings):
	* src/radio.c (radio_init), (radio_is_init), (radio_stop),
	(radio_set_freq), (radio_unmute), (radio_mute), (radio_get_stereo),
	(radio_get_signal), (radio_check_station):
	* src/radio.h:
	* src/tech.c (mixer_get_volume):
	* src/tech.h:
	* src/v4l1.c (v4l1_radio_init), (v4l1_radio_is_init),
	(v4l1_radio_set_freq), (v4l1_radio_mute), (v4l1_radio_get_stereo),
	(v4l1_radio_get_signal), (v4l1_radio_finalize),
	(v4l1_radio_dev_new):
	* src/v4l1.h:
	* src/v4l2.c (v4l2_radio_init), (v4l2_radio_is_init),
	(v4l2_radio_set_freq), (v4l2_radio_mute), (v4l2_radio_get_stereo),
	(v4l2_radio_get_signal), (v4l2_radio_finalize),
	(v4l2_radio_dev_new):
	* src/v4l2.h:
	Refactored backend so that it supports both v4l and v4l2 and selection can
	be made at runtime. The v4l2 code is based on the patch contributed by
	James Henstridge (bug #429005).



Added:
   trunk/src/radio.c
   trunk/src/radio.h
   trunk/src/v4l1.c
   trunk/src/v4l1.h
   trunk/src/v4l2.c
   trunk/src/v4l2.h
Modified:
   trunk/ChangeLog
   trunk/data/gnomeradio.schemas.in
   trunk/src/Makefile.am
   trunk/src/gui.c
   trunk/src/gui.h
   trunk/src/prefs.c
   trunk/src/tech.c
   trunk/src/tech.h

Modified: trunk/data/gnomeradio.schemas.in
==============================================================================
--- trunk/data/gnomeradio.schemas.in	(original)
+++ trunk/data/gnomeradio.schemas.in	Sun Apr 13 15:30:58 2008
@@ -37,6 +37,18 @@
     </schema>
 
     <schema>
+      <key>/schemas/apps/gnomeradio/driver</key>
+      <applyto>/apps/gnomeradio/driver</applyto>
+      <owner>gnomeradio</owner>
+      <type>string</type>
+      <default>any</default>
+      <locale name="C">
+	<short>Device driver</short>
+	<long>Specify the device driver to use (any, v4l1 or v4l2)</long>
+      </locale>
+    </schema>
+
+    <schema>
       <key>/schemas/apps/gnomeradio/mixer</key>
       <applyto>/apps/gnomeradio/mixer</applyto>
       <owner>gnomeradio</owner>

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Sun Apr 13 15:30:58 2008
@@ -10,7 +10,29 @@
 
 bin_PROGRAMS = gnomeradio
 
-gnomeradio_SOURCES = eggtrayicon.c bacon-volume.c trayicon.c gui.c tech.c prefs.c rec_tech.c record.c lirc.c \
-                     eggtrayicon.h bacon-volume.h trayicon.h gui.h tech.h prefs.h rec_tech.h record.h lirc.h
+gnomeradio_SOURCES = \
+            bacon-volume.h \
+            eggtrayicon.h \
+            gui.h \
+            prefs.h \
+            radio.h \
+            rec_tech.h \
+            record.h \
+            tech.h \
+            trayicon.h \
+            v4l1.h \
+            v4l2.h \
+            bacon-volume.c \
+            eggtrayicon.c \
+            gui.c \
+            lirc.c \
+            prefs.c \
+            radio.c \
+            rec_tech.c \
+            record.c \
+            tech.c \
+            trayicon.c \
+            v4l1.c \
+            v4l2.c
 
 gnomeradio_LDADD = $(GNOME_LIBS) $(GSTREAMER_LIBS) $(LIRC)

Modified: trunk/src/gui.c
==============================================================================
--- trunk/src/gui.c	(original)
+++ trunk/src/gui.c	Sun Apr 13 15:30:58 2008
@@ -29,6 +29,7 @@
 #include "gui.h"
 #include "trayicon.h"
 #include "tech.h"
+#include "radio.h"
 #include "rec_tech.h"
 #include "lirc.h"
 #include "prefs.h"
@@ -114,7 +115,7 @@
 	gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(fsd->progress), MAX(0, (freq - FREQ_MIN)/(FREQ_MAX - FREQ_MIN)));	
 	
 	freq += 1.0/STEPS;
-	radio_setfreq(freq);
+	radio_set_freq(freq);
 	
 	return TRUE;
 }
@@ -161,7 +162,7 @@
 		if (g_list_length(data.stations) > 0) {
 			gfloat f = *((gfloat*)data.stations->data);
 			adj->value = f*STEPS;
-			radio_setfreq(f);
+			radio_set_freq(f);
 			
 			GtkWidget *dialog;
 			GList *ptr;
@@ -223,10 +224,18 @@
 
 void start_radio(gboolean restart, GtkWidget *app)
 {
+    DriverType driver = DRIVER_ANY;
 	if (restart)
 		radio_stop();
 	
-	if (!radio_init(settings.device)) 
+    if (settings.driver) {
+        if (0 == strcmp(settings.driver, "v4l1"))
+            driver = DRIVER_V4L1;
+        if (0 == strcmp(settings.driver, "v4l2"))
+            driver = DRIVER_V4L2;
+    }
+
+	if (!radio_init(settings.device, driver))
 	{
 		char *caption = g_strdup_printf(_("Could not open device \"%s\"!"), settings.device);
 		char *detail = g_strdup_printf(_("Check your settings and make sure that no other\n"
@@ -308,8 +317,8 @@
 	freq[3] = (val % 100) / 10;
 	freq[4] = val % 10;
 
-	signal_strength = radio_getsignal();
-	is_stereo = radio_getstereo();
+	signal_strength = radio_get_signal();
+	is_stereo = radio_get_stereo();
 	
 	if (signal_strength > 3) signal_strength = 3;
 	if (signal_strength < 0) signal_strength = 0;
@@ -409,7 +418,7 @@
 	gtk_tooltips_set_tip(tooltips, freq_scale, buffer, NULL);
 	g_free(buffer);
 
-	radio_setfreq(adj->value/STEPS);
+	radio_set_freq(adj->value/STEPS);
 }
 
 static void volume_value_changed_cb(BaconVolumeButton *button, gpointer user_data)

Modified: trunk/src/gui.h
==============================================================================
--- trunk/src/gui.h	(original)
+++ trunk/src/gui.h	Sun Apr 13 15:30:58 2008
@@ -33,7 +33,8 @@
 	gchar *mixer_dev;
 	gchar *mixer;
 	gboolean mute_on_exit;
-		
+    gchar *driver;
+	
 	GList *presets;
 };
 

Modified: trunk/src/prefs.c
==============================================================================
--- trunk/src/prefs.c	(original)
+++ trunk/src/prefs.c	Sun Apr 13 15:30:58 2008
@@ -53,6 +53,7 @@
 	
 	/* Store general settings */
 	gconf_client_set_string(client, "/apps/gnomeradio/device", settings.device, NULL);
+	gconf_client_set_string(client, "/apps/gnomeradio/driver", settings.driver, NULL);
 	gconf_client_set_string(client, "/apps/gnomeradio/mixer", settings.mixer, NULL);
 	gconf_client_set_string(client, "/apps/gnomeradio/mixer-device", settings.mixer_dev, NULL);
 	gconf_client_set_bool(client, "/apps/gnomeradio/mute-on-exit", settings.mute_on_exit, NULL);
@@ -112,6 +113,9 @@
 	settings.device = gconf_client_get_string(client, "/apps/gnomeradio/device" , NULL);
 	if (!settings.device)
 		settings.device = g_strdup("/dev/radio");
+	settings.driver = gconf_client_get_string(client, "/apps/gnomeradio/driver" , NULL);
+	if (!settings.driver)
+		settings.driver = g_strdup("any");
 	settings.mixer = gconf_client_get_string(client, "/apps/gnomeradio/mixer", NULL);
 	if (!settings.mixer)
 		settings.mixer = g_strdup("line");

Added: trunk/src/radio.c
==============================================================================
--- (empty file)
+++ trunk/src/radio.c	Sun Apr 13 15:30:58 2008
@@ -0,0 +1,145 @@
+/*
+ *  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.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <assert.h>
+
+#include "radio.h"
+#include "v4l1.h"
+#include "v4l2.h"
+
+static RadioDev *dev;
+
+/*
+ * These functions handle the radio device
+ */
+ 
+int radio_init(char *device, DriverType driver)
+{
+    int rv = -1;
+	if (dev) {
+		radio_stop();
+	}
+
+	switch (driver) {
+		case DRIVER_V4L2:
+			goto try_v4l2;
+		case DRIVER_ANY:
+		case DRIVER_V4L1:
+		default:
+			goto try_v4l1;
+	}
+
+try_v4l1:
+	dev = v4l1_radio_dev_new();
+	rv = dev->init (dev, device);
+	if (rv == 0) {
+        fprintf(stderr, "Initializing v4l1 failed\n");
+		dev->finalize (dev);
+		dev = NULL;
+		if (driver != DRIVER_ANY)
+			goto failure;
+	} else {
+		goto success;
+	}
+
+try_v4l2:
+	dev = v4l2_radio_dev_new();
+	rv = dev->init (dev, device);
+	if (rv == 0) {
+        fprintf(stderr, "Initializing v4l2 failed\n");
+		dev->finalize (dev);
+		dev = NULL;
+		if (driver != DRIVER_ANY)
+			goto failure;
+	} else {
+		goto success;
+	}
+
+success:
+	radio_unmute();
+failure:
+
+	return rv;
+}
+
+int radio_is_init(void)
+{
+	if (dev) return dev->is_init (dev);
+	else return 0;
+}
+
+void radio_stop(void)
+{
+	radio_mute();
+	
+	if (dev) dev->finalize (dev);
+}
+
+void radio_set_freq(float frequency)
+{
+	if (dev) dev->set_freq (dev, frequency);
+}
+
+void radio_unmute(void)
+{
+	if (dev) dev->mute (dev, 0);
+}
+
+void radio_mute(void)
+{
+	if (dev) dev->mute (dev, 1);
+}
+
+int radio_get_stereo(void)
+{
+	if (dev) return dev->get_stereo (dev);
+	else return -1;
+}
+
+int radio_get_signal(void)
+{
+	if (dev) return dev->get_signal (dev);
+	else return -1;
+}
+
+int radio_check_station(float freq)
+{
+	static int a, b;
+	static float last;
+	int signal;
+	
+	signal = radio_get_signal();
+	
+	if (last == 0.0f)
+		last = freq;
+	
+	if ((a + b + signal > 8) && (fabsf(freq - last) > 0.25f)) {
+		a = b = 0;
+		last = freq;
+		return 1;
+	}
+	a = b;
+	b = signal;
+	return 0;
+}
+

Added: trunk/src/radio.h
==============================================================================
--- (empty file)
+++ trunk/src/radio.h	Sun Apr 13 15:30:58 2008
@@ -0,0 +1,58 @@
+/*
+ *  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.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _RADIO_H
+#define _RADIO_H
+
+typedef struct _RadioDev RadioDev;
+struct _RadioDev
+{
+	int  (*init)       (RadioDev *dev, char *device);
+	int  (*is_init)    (RadioDev *dev);
+	void (*set_freq)   (RadioDev *dev, float freq);
+	void (*mute)       (RadioDev *dev, int   mute);
+	int  (*get_stereo) (RadioDev *dev);
+	int  (*get_signal) (RadioDev *dev);
+	void (*finalize)   (RadioDev *dev);
+};
+
+typedef enum _DriverType DriverType;
+enum _DriverType
+{
+	DRIVER_ANY,
+	DRIVER_V4L1,
+	DRIVER_V4L2
+};
+
+int radio_init(char *device, DriverType type);
+
+int radio_is_init(void);
+
+void radio_stop(void);
+
+void radio_set_freq(float freq);
+
+int radio_check_station(float freq);
+
+void radio_unmute(void);
+
+void radio_mute(void);
+
+int radio_get_stereo(void);
+
+int radio_get_signal(void);
+
+#endif

Modified: trunk/src/tech.c
==============================================================================
--- trunk/src/tech.c	(original)
+++ trunk/src/tech.c	Sun Apr 13 15:30:58 2008
@@ -23,12 +23,11 @@
 #include <sys/ioctl.h>
 #include <assert.h>
 
-#include <linux/videodev.h>
 #include <sys/soundcard.h>
 
 #include "tech.h"
 
-static int freq_fact, fd = -1, mixer_fd = -1, mixer_src = -1;
+static int mixer_fd = -1, mixer_src = -1;
 static char *devices[] = SOUND_DEVICE_NAMES;
 
 /*
@@ -170,146 +169,3 @@
 	
 	return volume;
 }
-
-/*
- * These functions handle the radio device
- */
- 
-int radio_init(char *device)
-{
-	struct video_tuner tuner;
-	
-	if ((fd = open(device, O_RDONLY))< 0)
-		return 0;
-	
-	tuner.tuner = 0;
-	if (ioctl (fd, VIDIOCGTUNER, &tuner) < 0)
-		freq_fact = 16;
-	else
-	{
-		if ((tuner.flags & VIDEO_TUNER_LOW) == 0)
-			freq_fact = 16;
-		else 
-			freq_fact = 16000;
-	}		
-	
-	radio_unmute();
-	
-	return 1;
-}
-
-int radio_is_init(void)
-{
-	return (fd >= 0);
-}
-
-void radio_stop(void)
-{
-	radio_mute();
-	
-	if (fd >= 0)
-		close(fd);
-}
-
-int radio_setfreq(float freq)
-{
-    int ifreq = (freq+1.0/32)*freq_fact;
-    if (fd<0)
-    	return 0;
-    
-#if 0
-	printf("Setting to %i (= %.2f)\n", ifreq, freq);
-#endif
-	
-	if ((freq > 108) || (freq < 65))
-		return 1;
-
-	assert ((freq <= 108) && (freq > 65));
-
-    return ioctl(fd, VIDIOCSFREQ, &ifreq);
-}
-
-int radio_check_station(float freq)
-{
-	static int a, b;
-	static float last;
-	int signal;
-	
-	signal = radio_getsignal();
-	
-	if (last == 0.0f)
-		last = freq;
-	
-	if ((a + b + signal > 8) && (fabsf(freq - last) > 0.25f)) {
-		a = b = 0;
-		last = freq;
-		return 1;
-	}
-	a = b;
-	b = signal;
-	return 0;
-}	
-
-
-void radio_unmute(void)
-{
-    struct video_audio vid_aud;
-
-    if (fd<0)
-    	return;
-
-    if (ioctl(fd, VIDIOCGAUDIO, &vid_aud))
-		perror("VIDIOCGAUDIO");
-    /*if (vid_aud.volume == 0)*/
-	vid_aud.volume = 0xFFFF;
-    vid_aud.flags &= ~VIDEO_AUDIO_MUTE;
-	vid_aud.mode = VIDEO_SOUND_STEREO;
-	
-    if (ioctl(fd, VIDIOCSAUDIO, &vid_aud))
-		perror("VIDIOCSAUDIO");
-}
-
-void radio_mute(void)
-{
-    struct video_audio vid_aud;
-
-    if (fd<0)
-    	return;
-
-    if (ioctl(fd, VIDIOCGAUDIO, &vid_aud))
-		perror("VIDIOCGAUDIO");
-    vid_aud.flags |= VIDEO_AUDIO_MUTE;
-    if (ioctl(fd, VIDIOCSAUDIO, &vid_aud))
-		perror("VIDIOCSAUDIO");
-}
-
-int radio_getstereo()
-{
-    struct video_audio va;
-    va.mode=-1;
-
-    if (fd<0)
-    	return -1;
-    
-    if (ioctl (fd, VIDIOCGAUDIO, &va) < 0)
-		return -1;
-	if (va.mode == VIDEO_SOUND_STEREO)
-		return 1;
-	else 
-		return 0;
-}
-
-int radio_getsignal()
-{
-    struct video_tuner vt;
-    int signal;
-
-    if (fd<0)
-    	return -1;
-
-    memset(&vt,0,sizeof(vt));
-    ioctl (fd, VIDIOCGTUNER, &vt);
-    signal=vt.signal>>13;
-
-    return signal;
-}

Modified: trunk/src/tech.h
==============================================================================
--- trunk/src/tech.h	(original)
+++ trunk/src/tech.h	Sun Apr 13 15:30:58 2008
@@ -31,22 +31,4 @@
 
 int mixer_set_rec_device(void);
 
-int radio_init(char *device);
-
-int radio_is_init(void);
-
-void radio_stop(void);
-
-int radio_setfreq(float freq);
-
-int radio_check_station(float freq);
-
-void radio_unmute();
-
-void radio_mute();
-
-int radio_getstereo();
-
-int radio_getsignal();
-
 #endif

Added: trunk/src/v4l1.c
==============================================================================
--- (empty file)
+++ trunk/src/v4l1.c	Sun Apr 13 15:30:58 2008
@@ -0,0 +1,180 @@
+/*
+ *  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.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <assert.h>
+
+#include <linux/videodev.h>
+#include "radio.h"
+
+typedef struct _V4L1RadioDev V4L1RadioDev;
+struct _V4L1RadioDev
+{
+	struct _RadioDev parent;
+
+	int fd;
+	int freq_fact;
+};
+
+static int
+v4l1_radio_init(RadioDev *radio_dev, char *device)
+{
+	V4L1RadioDev *dev = (V4L1RadioDev*)radio_dev;
+	struct video_tuner tuner;
+	
+	if ((dev->fd = open(device, O_RDONLY)) < 0)
+		return 0;
+	
+	tuner.tuner = 0;
+	if (ioctl (dev->fd, VIDIOCGTUNER, &tuner) < 0)
+		dev->freq_fact = 16;
+	else
+	{
+		if ((tuner.flags & VIDEO_TUNER_LOW) == 0)
+			dev->freq_fact = 16;
+		else
+			dev->freq_fact = 16000;
+	}
+	
+	return 1;
+}
+
+int v4l1_radio_is_init(RadioDev *radio_dev)
+{
+	V4L1RadioDev *dev = (V4L1RadioDev*)radio_dev;
+	return (dev->fd >= 0);
+}
+
+static void
+v4l1_radio_set_freq(RadioDev *radio_dev, float freq)
+{
+	V4L1RadioDev *dev = (V4L1RadioDev*)radio_dev;
+    int ifreq;
+
+    if (dev->fd<0)
+    	return;
+    
+	ifreq = (freq+1.0/32)*dev->freq_fact;
+#if 0
+	printf("Setting to %i (= %.2f)\n", ifreq, freq);
+#endif
+
+	/* FIXME: Do we need really need these checks? */
+	if ((freq > 108) || (freq < 65))
+		return;
+
+	assert ((freq <= 108) && (freq > 65));
+
+    if (ioctl(dev->fd, VIDIOCSFREQ, &ifreq) < 0)
+		perror ("VIDIOCSFREQ");
+}
+
+static void
+v4l1_radio_mute(RadioDev *radio_dev, int mute)
+{
+	V4L1RadioDev *dev = (V4L1RadioDev*)radio_dev;
+    struct video_audio vid_aud;
+
+    if (dev->fd<0)
+    	return;
+
+    if (ioctl(dev->fd, VIDIOCGAUDIO, &vid_aud)) {
+		perror("VIDIOCGAUDIO");
+		memset (&vid_aud, 0, sizeof (struct video_audio));
+	}
+	if (mute) {
+    	vid_aud.flags |= VIDEO_AUDIO_MUTE;
+	} else {
+		vid_aud.volume = 0xFFFF;
+		vid_aud.flags &= ~VIDEO_AUDIO_MUTE;
+		vid_aud.mode = VIDEO_SOUND_STEREO;
+	}
+    if (ioctl(dev->fd, VIDIOCSAUDIO, &vid_aud))
+		perror("VIDIOCSAUDIO");
+}
+
+static int
+v4l1_radio_get_stereo(RadioDev *radio_dev)
+{
+	V4L1RadioDev *dev = (V4L1RadioDev*)radio_dev;
+    struct video_audio va;
+    va.mode=-1;
+
+    if (dev->fd<0)
+    	return -1;
+    
+    if (ioctl (dev->fd, VIDIOCGAUDIO, &va) < 0)
+		return -1;
+	if (va.mode == VIDEO_SOUND_STEREO)
+		return 1;
+	else 
+		return 0;
+}
+
+static int
+v4l1_radio_get_signal(RadioDev *radio_dev)
+{
+	V4L1RadioDev *dev = (V4L1RadioDev*)radio_dev;
+    struct video_tuner vt;
+    int signal;
+
+    if (dev->fd<0)
+    	return -1;
+
+    memset(&vt,0,sizeof(vt));
+    ioctl (dev->fd, VIDIOCGTUNER, &vt);
+    signal=vt.signal>>13;
+
+    return signal;
+}
+
+static void
+v4l1_radio_finalize(RadioDev *radio_dev)
+{
+	V4L1RadioDev *dev = (V4L1RadioDev*)radio_dev;
+	
+	if (dev->fd >= 0)
+		close(dev->fd);
+	free (dev);
+}
+
+RadioDev*
+v4l1_radio_dev_new (void)
+{
+    RadioDev *dev;
+	V4L1RadioDev *v4l1_dev;
+
+	v4l1_dev = malloc(sizeof(V4L1RadioDev));
+	v4l1_dev->fd = -1;
+	dev = (RadioDev*)v4l1_dev;
+
+	dev->init       = v4l1_radio_init;
+	dev->is_init    = v4l1_radio_is_init;
+	dev->set_freq   = v4l1_radio_set_freq;
+	dev->mute       = v4l1_radio_mute;
+	dev->get_stereo = v4l1_radio_get_stereo;
+	dev->get_signal = v4l1_radio_get_signal;
+	dev->finalize   = v4l1_radio_finalize;
+
+	return dev;
+}
+

Added: trunk/src/v4l1.h
==============================================================================
--- (empty file)
+++ trunk/src/v4l1.h	Sun Apr 13 15:30:58 2008
@@ -0,0 +1,25 @@
+/*
+ *  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.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _V4L1_H
+#define _V4L1_H
+
+#include <radio.h>
+
+RadioDev* v4l1_radio_dev_new (void);
+
+#endif
+

Added: trunk/src/v4l2.c
==============================================================================
--- (empty file)
+++ trunk/src/v4l2.c	Sun Apr 13 15:30:58 2008
@@ -0,0 +1,201 @@
+/*
+ *  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.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <math.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <assert.h>
+
+#include <linux/videodev2.h>
+#include "v4l2.h"
+
+typedef struct _V4L2RadioDev V4L2RadioDev;
+struct _V4L2RadioDev
+{
+	struct _RadioDev parent;
+
+	int fd;
+	int freq_fact;
+	int radio_rangelow;
+	int radio_rangehigh;
+};
+
+static int
+v4l2_radio_init(RadioDev *radio_dev, char *device)
+{
+	V4L2RadioDev *dev = (V4L2RadioDev*)radio_dev;
+	struct v4l2_capability caps;
+	struct v4l2_tuner tuner;
+	
+	if ((dev->fd = open(device, O_RDONLY))< 0)
+		goto err;
+	
+	/* does this device provide a tuner? */
+	memset(&caps, 0, sizeof(caps));
+	if (ioctl(dev->fd, VIDIOC_QUERYCAP, &caps) < 0) {
+		perror("VIDIOC_QUERYCAP");
+		goto err;
+	}
+	if ((caps.capabilities & V4L2_CAP_TUNER) == 0) {
+		fprintf(stderr, "Not a radio tuner\n");
+		goto err;
+	}
+
+	/* check the tuner */
+	memset(&tuner, 0, sizeof(tuner));
+	tuner.index = 0;
+	if (ioctl(dev->fd, VIDIOC_G_TUNER, &tuner) < 0) {
+		perror("VIDIOC_G_TUNER");
+		goto err;
+	}
+	if (tuner.type != V4L2_TUNER_RADIO) {
+		fprintf(stderr, "Not a radio tuner\n");
+		goto err;
+	}
+	/* Does this tuner expect data in 62.5Hz or 62.5kHz multiples? */
+	dev->radio_rangelow = tuner.rangelow;
+	dev->radio_rangehigh = tuner.rangehigh;
+	if ((tuner.capability & V4L2_TUNER_CAP_LOW) != 0)
+		dev->freq_fact = 16000;
+	else
+		dev->freq_fact = 16;
+	
+	return 1;
+
+ err:
+	if (dev->fd >= 0)
+		close(dev->fd);
+	dev->fd = -1;
+	return 0;
+}
+
+static int
+v4l2_radio_is_init(RadioDev *radio_dev)
+{
+	V4L2RadioDev *dev = (V4L2RadioDev*)radio_dev;
+	return (dev->fd >= 0);
+}
+
+static void
+v4l2_radio_set_freq(RadioDev *radio_dev, float frequency)
+{
+	V4L2RadioDev *dev = (V4L2RadioDev*)radio_dev;
+	struct v4l2_frequency freq;
+
+	if (dev->fd<0)
+		return;
+
+	memset(&freq, 0, sizeof(freq));
+	freq.tuner = 0;
+	freq.type = V4L2_TUNER_RADIO;
+	freq.frequency = frequency * dev->freq_fact;
+
+	if (freq.frequency < dev->radio_rangelow ||
+	    freq.frequency > dev->radio_rangehigh)
+		return;
+	if (ioctl(dev->fd, VIDIOC_S_FREQUENCY, &freq) < 0)
+		perror("VIDIOC_S_FREQUENCY");
+}
+
+static void
+v4l2_radio_mute(RadioDev *radio_dev, int mute)
+{
+	V4L2RadioDev *dev = (V4L2RadioDev*)radio_dev;
+	struct v4l2_control control;
+
+	if (dev->fd<0)
+		return;
+
+	memset(&control, 0, sizeof(control));
+	control.id = V4L2_CID_AUDIO_MUTE;
+	control.value = mute;
+	if (ioctl(dev->fd, VIDIOC_S_CTRL, &control) < 0)
+		perror("VIDIOC_S_CTRL");
+}
+
+static int
+v4l2_radio_get_stereo(RadioDev *radio_dev)
+{
+	V4L2RadioDev *dev = (V4L2RadioDev*)radio_dev;
+	struct v4l2_tuner tuner;
+
+	if (dev->fd<0)
+		return -1;
+
+	memset(&tuner, 0, sizeof(tuner));
+	tuner.index = 0;
+	if (ioctl(dev->fd, VIDIOC_G_TUNER, &tuner) < 0) {
+		perror("VIDIOC_G_TUNER");
+		return -1;
+	}
+
+	return tuner.audmode == V4L2_TUNER_MODE_STEREO;
+}
+
+static int
+v4l2_radio_get_signal(RadioDev *radio_dev)
+{
+	V4L2RadioDev *dev = (V4L2RadioDev*)radio_dev;
+	struct v4l2_tuner tuner;
+
+	if (dev->fd<0)
+		return -1;
+
+	memset(&tuner, 0, sizeof(tuner));
+	tuner.index = 0;
+	if (ioctl(dev->fd, VIDIOC_G_TUNER, &tuner) < 0) {
+		perror("VIDIOC_G_TUNER");
+		return -1;
+	}
+
+	return tuner.signal >> 13;
+}
+
+static void
+v4l2_radio_finalize(RadioDev *radio_dev)
+{
+	V4L2RadioDev *dev = (V4L2RadioDev*)radio_dev;
+	
+	if (dev->fd >= 0)
+		close(dev->fd);
+	free (dev);
+}
+
+RadioDev*
+v4l2_radio_dev_new (void)
+{
+    RadioDev *dev;
+	V4L2RadioDev *v4l2_dev;
+
+	v4l2_dev = malloc (sizeof (V4L2RadioDev));
+	v4l2_dev->fd = -1;
+
+	dev = (RadioDev*)v4l2_dev;
+	dev->init       = v4l2_radio_init;
+	dev->is_init    = v4l2_radio_is_init;
+	dev->set_freq   = v4l2_radio_set_freq;
+	dev->mute       = v4l2_radio_mute;
+	dev->get_stereo = v4l2_radio_get_stereo;
+	dev->get_signal = v4l2_radio_get_signal;
+	dev->finalize   = v4l2_radio_finalize;
+
+	return dev;
+}
+

Added: trunk/src/v4l2.h
==============================================================================
--- (empty file)
+++ trunk/src/v4l2.h	Sun Apr 13 15:30:58 2008
@@ -0,0 +1,25 @@
+/*
+ *  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.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _V4L2_H
+#define _V4L2_H
+
+#include <radio.h>
+
+RadioDev* v4l2_radio_dev_new (void);
+
+#endif
+



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]