[staging-next 1/3 V2] staging/easycap: make OSS compilation optional instead of ALSA

Tomas Winkler tomas.winkler at intel.com
Mon Jan 24 15:08:20 UTC 2011


OSS is deprecated yet currently it is reported to be more stable
therefore we keep it but make it optional
Revert the conditional compilation:
	add  CONFIG_EASYCAP_OSS and kill EASYCAP_NEEDS_ALSA
move oss-only code from easycap_sound.c to easycap_sound_oss.c

Signed-off-by: Tomas Winkler <tomas.winkler at intel.com>

 create mode 100644 drivers/staging/easycap/easycap_sound_oss.c

 create mode 100644 drivers/staging/easycap/easycap_sound_oss.c
---
V2: fix typo in Kconfig

 drivers/staging/easycap/Kconfig             |   14 +-
 drivers/staging/easycap/Makefile            |   10 +-
 drivers/staging/easycap/easycap.h           |   25 +-
 drivers/staging/easycap/easycap_ioctl.c     |    4 +-
 drivers/staging/easycap/easycap_main.c      |   36 +-
 drivers/staging/easycap/easycap_sound.c     |  712 +--------------------------
 drivers/staging/easycap/easycap_sound_oss.c |  730 +++++++++++++++++++++++++++
 7 files changed, 789 insertions(+), 742 deletions(-)
 create mode 100644 drivers/staging/easycap/easycap_sound_oss.c

diff --git a/drivers/staging/easycap/Kconfig b/drivers/staging/easycap/Kconfig
index b8d44dd..78f72df 100644
--- a/drivers/staging/easycap/Kconfig
+++ b/drivers/staging/easycap/Kconfig
@@ -1,6 +1,6 @@
 config EASYCAP
 	tristate "EasyCAP USB ID 05e1:0408 support"
-	depends on USB && VIDEO_DEV && SND
+	depends on USB && VIDEO_DEV && SOUND
 
 	---help---
 	  This is an integrated audio/video driver for EasyCAP cards with
@@ -15,6 +15,18 @@ config EASYCAP
 	  To compile this driver as a module, choose M here: the
 	  module will be called easycap
 
+config EASYCAP_OSS
+	bool "OSS (DEPRECATED)"
+	depends on EASYCAP && SOUND_OSS_CORE
+
+	---help---
+	  Say 'Y' if you prefer Open Sound System (OSS) interface
+
+	  This will disable Advanced Linux Sound Architecture (ALSA) binding.
+
+	  Once binding to ALSA interface will be stable this option will be
+          removed.
+
 config EASYCAP_DEBUG
 	bool "Enable EasyCAP driver debugging"
 	depends on EASYCAP
diff --git a/drivers/staging/easycap/Makefile b/drivers/staging/easycap/Makefile
index 226a779..a01ca11 100644
--- a/drivers/staging/easycap/Makefile
+++ b/drivers/staging/easycap/Makefile
@@ -1,5 +1,10 @@
-easycap-objs      := easycap_main.o easycap_low.o easycap_sound.o \
-		     easycap_ioctl.o easycap_settings.o easycap_testcard.o
+easycap-objs := easycap_main.o
+easycap-objs += easycap_low.o
+easycap-objs += easycap_ioctl.o
+easycap-objs += easycap_settings.o
+easycap-objs += easycap_testcard.o
+easycap-objs += easycap_sound.o
+easycap-$(CONFIG_EASYCAP_OSS) += easycap_sound_oss.o
 
 obj-$(CONFIG_EASYCAP)       += easycap.o
 
@@ -8,5 +13,4 @@ ccflags-y += -DEASYCAP_IS_VIDEODEV_CLIENT
 ccflags-y += -DEASYCAP_NEEDS_V4L2_DEVICE_H
 ccflags-y += -DEASYCAP_NEEDS_V4L2_FOPS
 ccflags-y += -DEASYCAP_NEEDS_UNLOCKED_IOCTL
-ccflags-y += -DEASYCAP_NEEDS_ALSA
 
diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h
index d751e75..55ff0d5 100644
--- a/drivers/staging/easycap/easycap.h
+++ b/drivers/staging/easycap/easycap.h
@@ -59,9 +59,9 @@
  */
 /*---------------------------------------------------------------------------*/
 #undef  EASYCAP_TESTCARD
-#if (!defined(EASYCAP_NEEDS_ALSA))
+#ifdef CONFIG_EASYCAP_OSS
 #undef  EASYCAP_TESTTONE
-#endif /*EASYCAP_NEEDS_ALSA*/
+#endif /* CONFIG_EASYCAP_OSS */
 /*---------------------------------------------------------------------------*/
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -81,7 +81,7 @@
 #include <linux/delay.h>
 #include <linux/types.h>
 
-#if defined(EASYCAP_NEEDS_ALSA)
+#ifndef CONFIG_EASYCAP_OSS
 #include <linux/vmalloc.h>
 #include <linux/sound.h>
 #include <sound/core.h>
@@ -90,7 +90,7 @@
 #include <sound/info.h>
 #include <sound/initval.h>
 #include <sound/control.h>
-#endif /*EASYCAP_NEEDS_ALSA*/
+#endif /* !CONFIG_EASYCAP_OSS */
 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
 #if defined(EASYCAP_IS_VIDEODEV_CLIENT)
 #include <media/v4l2-dev.h>
@@ -445,7 +445,7 @@ __s16 oldaudio;
  *  ALSA
  */
 /*---------------------------------------------------------------------------*/
-#if defined(EASYCAP_NEEDS_ALSA)
+#ifndef CONFIG_EASYCAP_OSS
 	struct snd_pcm_hardware alsa_hardware;
 	struct snd_card *psnd_card;
 	struct snd_pcm *psnd_pcm;
@@ -453,7 +453,7 @@ __s16 oldaudio;
 	int dma_fill;
 	int dma_next;
 	int dma_read;
-#endif /*EASYCAP_NEEDS_ALSA*/
+#endif /* !CONFIG_EASYCAP_OSS */
 /*---------------------------------------------------------------------------*/
 /*
  *  SOUND PROPERTIES
@@ -537,7 +537,7 @@ int              adjust_volume(struct easycap *, int);
  *  AUDIO FUNCTION PROTOTYPES
  */
 /*---------------------------------------------------------------------------*/
-#if defined(EASYCAP_NEEDS_ALSA)
+#ifndef CONFIG_EASYCAP_OSS
 int		easycap_alsa_probe(struct easycap *);
 
 void            easycap_alsa_complete(struct urb *);
@@ -553,7 +553,7 @@ int		easycap_alsa_trigger(struct snd_pcm_substream *, int);
 snd_pcm_uframes_t easycap_alsa_pointer(struct snd_pcm_substream *);
 struct page	*easycap_alsa_page(struct snd_pcm_substream *, unsigned long);
 
-#else
+#else /* CONFIG_EASYCAP_OSS */
 void             easyoss_complete(struct urb *);
 ssize_t          easyoss_read(struct file *, char __user *, size_t, loff_t *);
 int              easyoss_open(struct inode *, struct file *);
@@ -564,7 +564,8 @@ int              easyoss_ioctl(struct inode *, struct file *, unsigned int,
 								unsigned long);
 unsigned int     easyoss_poll(struct file *, poll_table *);
 void             easyoss_delete(struct kref *);
-#endif /*EASYCAP_NEEDS_ALSA*/
+#endif /* !CONFIG_EASYCAP_OSS */
+
 int              easycap_sound_setup(struct easycap *);
 int              submit_audio_urbs(struct easycap *);
 int              kill_audio_urbs(struct easycap *);
@@ -715,13 +716,13 @@ extern struct easycap_format easycap_format[];
 extern struct v4l2_queryctrl easycap_control[];
 extern struct usb_driver easycap_usb_driver;
 extern struct easycap_dongle easycapdc60_dongle[];
-#if defined(EASYCAP_NEEDS_ALSA)
+#ifndef CONFIG_EASYCAP_OSS
 extern struct snd_pcm_ops easycap_alsa_ops;
 extern struct snd_pcm_hardware easycap_pcm_hardware;
 extern struct snd_card *psnd_card;
-#else
+#else /* CONFIG_EASYCAP_OSS */
 extern struct usb_class_driver easyoss_class;
 extern const struct file_operations easyoss_fops;
-#endif /*EASYCAP_NEEDS_ALSA*/
+#endif /* !CONFIG_EASYCAP_OSS */
 
 #endif /* !__EASYCAP_H__  */
diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c
index 4389103..6995163 100644
--- a/drivers/staging/easycap/easycap_ioctl.c
+++ b/drivers/staging/easycap/easycap_ioctl.c
@@ -2517,7 +2517,7 @@ JOM(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd);
 return 0;
 }
 /*****************************************************************************/
-#if !defined(EASYCAP_NEEDS_ALSA)
+#ifdef CONFIG_EASYCAP_OSS
 /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
 #if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \
 	(defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)))
@@ -2821,6 +2821,6 @@ default: {
 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
 return 0;
 }
-#endif /*EASYCAP_NEEDS_ALSA*/
+#endif /* CONFIG_EASYCAP_OSS */
 /*****************************************************************************/
 
diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c
index cc1460b..d1d7a48 100644
--- a/drivers/staging/easycap/easycap_main.c
+++ b/drivers/staging/easycap/easycap_main.c
@@ -962,7 +962,7 @@ for (k = 0;  k < AUDIO_ISOC_BUFFER_MANY;  k++) {
 JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n",
 					m * (0x01 << AUDIO_ISOC_ORDER));
 /*---------------------------------------------------------------------------*/
-#if !defined(EASYCAP_NEEDS_ALSA)
+#ifdef CONFIG_EASYCAP_OSS
 JOM(4, "freeing audio buffers.\n");
 gone = 0;
 for (k = 0;  k < peasycap->audio_buffer_page_many;  k++) {
@@ -974,7 +974,7 @@ for (k = 0;  k < peasycap->audio_buffer_page_many;  k++) {
 	}
 }
 JOM(4, "easyoss_delete(): audio buffers freed: %i pages\n", gone);
-#endif /*!EASYCAP_NEEDS_ALSA*/
+#endif /* CONFIG_EASYCAP_OSS */
 /*---------------------------------------------------------------------------*/
 JOM(4, "freeing easycap structure.\n");
 allocation_video_urb    = peasycap->allocation_video_urb;
@@ -4350,7 +4350,7 @@ case 2: {
 	INIT_LIST_HEAD(&(peasycap->urb_audio_head));
 	peasycap->purb_audio_head = &(peasycap->urb_audio_head);
 
-#if !defined(EASYCAP_NEEDS_ALSA)
+#ifdef CONFIG_EASYCAP_OSS
 	JOM(4, "allocating an audio buffer\n");
 	JOM(4, ".... scattered over %i pages\n",
 					peasycap->audio_buffer_page_many);
@@ -4375,7 +4375,7 @@ case 2: {
 	peasycap->audio_fill = 0;
 	peasycap->audio_read = 0;
 	JOM(4, "allocation of audio buffer done:  %i pages\n", k);
-#endif /*!EASYCAP_NEEDS_ALSA*/
+#endif /* CONFIG_EASYCAP_OSS */
 /*---------------------------------------------------------------------------*/
 	JOM(4, "allocating %i isoc audio buffers of size %i\n",
 		AUDIO_ISOC_BUFFER_MANY, peasycap->audio_isoc_buffer_size);
@@ -4450,11 +4450,11 @@ case 2: {
 				"peasycap->audio_isoc_buffer[.].pgo;\n");
 			JOM(4, "  purb->transfer_buffer_length = %i;\n",
 					peasycap->audio_isoc_buffer_size);
-#if defined(EASYCAP_NEEDS_ALSA)
-			JOM(4, "  purb->complete = easycap_alsa_complete;\n");
-#else
+#ifdef CONFIG_EASYCAP_OSS
 			JOM(4, "  purb->complete = easyoss_complete;\n");
-#endif /*EASYCAP_NEEDS_ALSA*/
+#else /* CONFIG_EASYCAP_OSS */
+			JOM(4, "  purb->complete = easycap_alsa_complete;\n");
+#endif /* CONFIG_EASYCAP_OSS */
 			JOM(4, "  purb->context = peasycap;\n");
 			JOM(4, "  purb->start_frame = 0;\n");
 			JOM(4, "  purb->number_of_packets = %i;\n",
@@ -4477,11 +4477,11 @@ case 2: {
 		purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo;
 		purb->transfer_buffer_length =
 					peasycap->audio_isoc_buffer_size;
-#if defined(EASYCAP_NEEDS_ALSA)
-		purb->complete = easycap_alsa_complete;
-#else
+#ifdef CONFIG_EASYCAP_OSS
 		purb->complete = easyoss_complete;
-#endif /*EASYCAP_NEEDS_ALSA*/
+#else /* CONFIG_EASYCAP_OSS */
+		purb->complete = easycap_alsa_complete;
+#endif /* CONFIG_EASYCAP_OSS */
 		purb->context = peasycap;
 		purb->start_frame = 0;
 		purb->number_of_packets = peasycap->audio_isoc_framesperdesc;
@@ -4504,7 +4504,7 @@ case 2: {
  *  THE AUDIO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
  */
 /*---------------------------------------------------------------------------*/
-#if defined(EASYCAP_NEEDS_ALSA)
+#ifndef CONFIG_EASYCAP_OSS
 	JOM(4, "initializing ALSA card\n");
 
 	rc = easycap_alsa_probe(peasycap);
@@ -4518,7 +4518,7 @@ case 2: {
 		(peasycap->registered_audio)++;
 	}
 
-#else /*EASYCAP_NEEDS_ALSA*/
+#else /* CONFIG_EASYCAP_OSS */
 	rc = usb_register_dev(pusb_interface, &easyoss_class);
 	if (0 != rc) {
 		SAY("ERROR: usb_register_dev() failed\n");
@@ -4536,7 +4536,7 @@ case 2: {
  */
 /*---------------------------------------------------------------------------*/
 	SAM("easyoss attached to minor #%d\n", pusb_interface->minor);
-#endif /*EASYCAP_NEEDS_ALSA*/
+#endif /* CONFIG_EASYCAP_OSS */
 
 	break;
 }
@@ -4774,7 +4774,7 @@ case 2: {
 		JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd);
 	} else
 		SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd);
-#if defined(EASYCAP_NEEDS_ALSA)
+#ifndef CONFIG_EASYCAP_OSS
 
 
 
@@ -4786,12 +4786,12 @@ case 2: {
 	}
 
 
-#else /*EASYCAP_NEEDS_ALSA*/
+#else /* CONFIG_EASYCAP_OSS */
 	usb_deregister_dev(pusb_interface, &easyoss_class);
 	(peasycap->registered_audio)--;
 	JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber);
 	SAM("easyoss detached from minor #%d\n", minor);
-#endif /*EASYCAP_NEEDS_ALSA*/
+#endif /* CONFIG_EASYCAP_OSS */
 
 	if (0 <= kd && DONGLE_MANY > kd) {
 		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c
index 05d9eed..07dd7aa 100644
--- a/drivers/staging/easycap/easycap_sound.c
+++ b/drivers/staging/easycap/easycap_sound.c
@@ -30,7 +30,7 @@
 
 #include "easycap.h"
 
-#if defined(EASYCAP_NEEDS_ALSA)
+#ifndef CONFIG_EASYCAP_OSS
 /*--------------------------------------------------------------------------*/
 /*
  *  PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE
@@ -669,707 +669,7 @@ return vmalloc_to_page(pss->runtime->dma_area + offset);
 }
 /*****************************************************************************/
 
-#else /*!EASYCAP_NEEDS_ALSA*/
-
-/*****************************************************************************/
-/****************************                       **************************/
-/****************************   Open Sound System   **************************/
-/****************************                       **************************/
-/*****************************************************************************/
-/*--------------------------------------------------------------------------*/
-/*
- *  PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE
- */
-/*--------------------------------------------------------------------------*/
-const struct file_operations easyoss_fops = {
-	.owner		= THIS_MODULE,
-	.open		= easyoss_open,
-	.release	= easyoss_release,
-#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)
-	.unlocked_ioctl	= easyoss_ioctl_noinode,
-#else
-	.ioctl		= easyoss_ioctl,
-#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/
-	.read		= easyoss_read,
-	.llseek		= no_llseek,
-};
-struct usb_class_driver easyoss_class = {
-.name = "usb/easyoss%d",
-.fops = &easyoss_fops,
-.minor_base = USB_SKEL_MINOR_BASE,
-};
-/*****************************************************************************/
-/*---------------------------------------------------------------------------*/
-/*
- *  ON COMPLETION OF AN AUDIO URB ITS DATA IS COPIED TO THE AUDIO BUFFERS
- *  PROVIDED peasycap->audio_idle IS ZERO.  REGARDLESS OF THIS BEING TRUE,
- *  IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO.
- */
-/*---------------------------------------------------------------------------*/
-void
-easyoss_complete(struct urb *purb)
-{
-struct easycap *peasycap;
-struct data_buffer *paudio_buffer;
-__u8 *p1, *p2;
-__s16 s16;
-int i, j, more, much, leap, rc;
-#if defined(UPSAMPLE)
-int k;
-__s16 oldaudio, newaudio, delta;
-#endif /*UPSAMPLE*/
-
-JOT(16, "\n");
-
-if (NULL == purb) {
-	SAY("ERROR: purb is NULL\n");
-	return;
-}
-peasycap = purb->context;
-if (NULL == peasycap) {
-	SAY("ERROR: peasycap is NULL\n");
-	return;
-}
-if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
-	SAY("ERROR: bad peasycap\n");
-	return;
-}
-much = 0;
-if (peasycap->audio_idle) {
-	JOM(16, "%i=audio_idle  %i=audio_isoc_streaming\n",
-			peasycap->audio_idle, peasycap->audio_isoc_streaming);
-	if (peasycap->audio_isoc_streaming) {
-		rc = usb_submit_urb(purb, GFP_ATOMIC);
-		if (rc) {
-			if (-ENODEV != rc && -ENOENT != rc) {
-				SAM("ERROR: while %i=audio_idle, "
-				    "usb_submit_urb() failed with rc: -%s: %d\n",
-					peasycap->audio_idle,
-					strerror(rc), rc);
-			}
-		}
-	}
-return;
-}
-/*---------------------------------------------------------------------------*/
-if (purb->status) {
-	if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) {
-		JOM(16, "urb status -ESHUTDOWN or -ENOENT\n");
-		return;
-	}
-	SAM("ERROR: non-zero urb status: -%s: %d\n",
-		strerror(purb->status), purb->status);
-	goto resubmit;
-}
-/*---------------------------------------------------------------------------*/
-/*
- *  PROCEED HERE WHEN NO ERROR
- */
-/*---------------------------------------------------------------------------*/
-#if defined(UPSAMPLE)
-oldaudio = peasycap->oldaudio;
-#endif /*UPSAMPLE*/
-
-for (i = 0;  i < purb->number_of_packets; i++) {
-	if (!purb->iso_frame_desc[i].status) {
-
-		SAM("-%s\n", strerror(purb->iso_frame_desc[i].status));
-
-		more = purb->iso_frame_desc[i].actual_length;
-
-#if defined(TESTTONE)
-		if (!more)
-			more = purb->iso_frame_desc[i].length;
-#endif
-
-		if (!more)
-			peasycap->audio_mt++;
-		else {
-			if (peasycap->audio_mt) {
-				JOM(12, "%4i empty audio urb frames\n",
-							peasycap->audio_mt);
-				peasycap->audio_mt = 0;
-			}
-
-			p1 = (__u8 *)(purb->transfer_buffer +
-					purb->iso_frame_desc[i].offset);
-
-			leap = 0;
-			p1 += leap;
-			more -= leap;
-/*---------------------------------------------------------------------------*/
-/*
- *  COPY more BYTES FROM ISOC BUFFER TO AUDIO BUFFER,
- *  CONVERTING 8-BIT MONO TO 16-BIT SIGNED LITTLE-ENDIAN SAMPLES IF NECESSARY
- */
-/*---------------------------------------------------------------------------*/
-			while (more) {
-				if (0 > more) {
-					SAM("MISTAKE: more is negative\n");
-					return;
-				}
-				if (peasycap->audio_buffer_page_many <=
-							peasycap->audio_fill) {
-					SAM("ERROR: bad "
-						"peasycap->audio_fill\n");
-					return;
-				}
-
-				paudio_buffer = &peasycap->audio_buffer
-							[peasycap->audio_fill];
-				if (PAGE_SIZE < (paudio_buffer->pto -
-						paudio_buffer->pgo)) {
-					SAM("ERROR: bad paudio_buffer->pto\n");
-					return;
-				}
-				if (PAGE_SIZE == (paudio_buffer->pto -
-							paudio_buffer->pgo)) {
-
-#if defined(TESTTONE)
-					easyoss_testtone(peasycap,
-							peasycap->audio_fill);
-#endif /*TESTTONE*/
-
-					paudio_buffer->pto =
-							paudio_buffer->pgo;
-					(peasycap->audio_fill)++;
-					if (peasycap->
-						audio_buffer_page_many <=
-							peasycap->audio_fill)
-						peasycap->audio_fill = 0;
-
-					JOM(8, "bumped peasycap->"
-							"audio_fill to %i\n",
-							peasycap->audio_fill);
-
-					paudio_buffer = &peasycap->
-							audio_buffer
-							[peasycap->audio_fill];
-					paudio_buffer->pto =
-							paudio_buffer->pgo;
-
-					if (!(peasycap->audio_fill %
-						peasycap->
-						audio_pages_per_fragment)) {
-						JOM(12, "wakeup call on wq_"
-						"audio, %i=frag reading  %i"
-						"=fragment fill\n",
-						(peasycap->audio_read /
-						peasycap->
-						audio_pages_per_fragment),
-						(peasycap->audio_fill /
-						peasycap->
-						audio_pages_per_fragment));
-						wake_up_interruptible
-						(&(peasycap->wq_audio));
-					}
-				}
-
-				much = PAGE_SIZE - (int)(paudio_buffer->pto -
-							 paudio_buffer->pgo);
-
-				if (false == peasycap->microphone) {
-					if (much > more)
-						much = more;
-
-					memcpy(paudio_buffer->pto, p1, much);
-					p1 += much;
-					more -= much;
-				} else {
-#if defined(UPSAMPLE)
-					if (much % 16)
-						JOM(8, "MISTAKE? much"
-						" is not divisible by 16\n");
-					if (much > (16 *
-							more))
-						much = 16 *
-							more;
-					p2 = (__u8 *)paudio_buffer->pto;
-
-					for (j = 0;  j < (much/16);  j++) {
-						newaudio =  ((int) *p1) - 128;
-						newaudio = 128 *
-								newaudio;
-
-						delta = (newaudio - oldaudio)
-									/ 4;
-						s16 = oldaudio + delta;
-
-						for (k = 0;  k < 4;  k++) {
-							*p2 = (0x00FF & s16);
-							*(p2 + 1) = (0xFF00 &
-								s16) >> 8;
-							p2 += 2;
-							*p2 = (0x00FF & s16);
-							*(p2 + 1) = (0xFF00 &
-								s16) >> 8;
-							p2 += 2;
-
-							s16 += delta;
-						}
-						p1++;
-						more--;
-						oldaudio = s16;
-					}
-#else /*!UPSAMPLE*/
-					if (much > (2 * more))
-						much = 2 * more;
-					p2 = (__u8 *)paudio_buffer->pto;
-
-					for (j = 0;  j < (much / 2);  j++) {
-						s16 =  ((int) *p1) - 128;
-						s16 = 128 *
-								s16;
-						*p2 = (0x00FF & s16);
-						*(p2 + 1) = (0xFF00 & s16) >>
-									8;
-						p1++;  p2 += 2;
-						more--;
-					}
-#endif /*UPSAMPLE*/
-				}
-				(paudio_buffer->pto) += much;
-			}
-		}
-	} else {
-		JOM(12, "discarding audio samples because "
-			"%i=purb->iso_frame_desc[i].status\n",
-				purb->iso_frame_desc[i].status);
-	}
-
-#if defined(UPSAMPLE)
-peasycap->oldaudio = oldaudio;
-#endif /*UPSAMPLE*/
-
-}
-/*---------------------------------------------------------------------------*/
-/*
- *  RESUBMIT THIS URB
- */
-/*---------------------------------------------------------------------------*/
-resubmit:
-if (peasycap->audio_isoc_streaming) {
-	rc = usb_submit_urb(purb, GFP_ATOMIC);
-	if (0 != rc) {
-		if (-ENODEV != rc && -ENOENT != rc) {
-			SAM("ERROR: while %i=audio_idle, "
-				"usb_submit_urb() failed "
-				"with rc: -%s: %d\n", peasycap->audio_idle,
-				strerror(rc), rc);
-		}
-	}
-}
-return;
-}
-/*****************************************************************************/
-/*---------------------------------------------------------------------------*/
-/*
- *  THE AUDIO URBS ARE SUBMITTED AT THIS EARLY STAGE SO THAT IT IS POSSIBLE TO
- *  STREAM FROM /dev/easyoss1 WITH SIMPLE PROGRAMS SUCH AS cat WHICH DO NOT
- *  HAVE AN IOCTL INTERFACE.
- */
-/*---------------------------------------------------------------------------*/
-int
-easyoss_open(struct inode *inode, struct file *file)
-{
-struct usb_interface *pusb_interface;
-struct easycap *peasycap;
-int subminor;
-/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
-#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
-#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
-struct v4l2_device *pv4l2_device;
-#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
-#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
-/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
-
-JOT(4, "begins\n");
-
-subminor = iminor(inode);
-
-pusb_interface = usb_find_interface(&easycap_usb_driver, subminor);
-if (NULL == pusb_interface) {
-	SAY("ERROR: pusb_interface is NULL\n");
-	SAY("ending unsuccessfully\n");
-	return -1;
-}
-peasycap = usb_get_intfdata(pusb_interface);
-if (NULL == peasycap) {
-	SAY("ERROR: peasycap is NULL\n");
-	SAY("ending unsuccessfully\n");
-	return -1;
-}
-/*---------------------------------------------------------------------------*/
-#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
-#
-/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
-#else
-#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
-/*---------------------------------------------------------------------------*/
-/*
- *  SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS
- *  BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(),
- *  REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE.
- *  TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED.
-*/
-/*---------------------------------------------------------------------------*/
-if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
-	pv4l2_device = usb_get_intfdata(pusb_interface);
-	if ((struct v4l2_device *)NULL == pv4l2_device) {
-		SAY("ERROR: pv4l2_device is NULL\n");
-		return -EFAULT;
-	}
-	peasycap = (struct easycap *)
-		container_of(pv4l2_device, struct easycap, v4l2_device);
-}
-#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
-#
-#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
-/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
-/*---------------------------------------------------------------------------*/
-if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
-	SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
-	return -EFAULT;
-}
-/*---------------------------------------------------------------------------*/
-
-file->private_data = peasycap;
-
-if (0 != easycap_sound_setup(peasycap)) {
-	;
-	;
-}
-return 0;
-}
-/*****************************************************************************/
-int
-easyoss_release(struct inode *inode, struct file *file)
-{
-struct easycap *peasycap;
-
-JOT(4, "begins\n");
-
-peasycap = file->private_data;
-if (NULL == peasycap) {
-	SAY("ERROR:  peasycap is NULL.\n");
-	return -EFAULT;
-}
-if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
-	SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
-	return -EFAULT;
-}
-if (0 != kill_audio_urbs(peasycap)) {
-	SAM("ERROR: kill_audio_urbs() failed\n");
-	return -EFAULT;
-}
-JOM(4, "ending successfully\n");
-return 0;
-}
-/*****************************************************************************/
-ssize_t
-easyoss_read(struct file *file, char __user *puserspacebuffer,
-						size_t kount, loff_t *poff)
-{
-struct timeval timeval;
-long long int above, below, mean;
-struct signed_div_result sdr;
-unsigned char *p0;
-long int kount1, more, rc, l0, lm;
-int fragment, kd;
-struct easycap *peasycap;
-struct data_buffer *pdata_buffer;
-size_t szret;
-
-/*---------------------------------------------------------------------------*/
-/*
- *  DO A BLOCKING READ TO TRANSFER DATA TO USER SPACE.
- *
- ******************************************************************************
- *****  N.B.  IF THIS FUNCTION RETURNS 0, NOTHING IS SEEN IN USER SPACE. ******
- *****        THIS CONDITION SIGNIFIES END-OF-FILE.                      ******
- ******************************************************************************
- */
-/*---------------------------------------------------------------------------*/
-
-JOT(8, "%5i=kount  %5i=*poff\n", (int)kount, (int)(*poff));
-
-if (NULL == file) {
-	SAY("ERROR:  file is NULL\n");
-	return -ERESTARTSYS;
-}
-peasycap = file->private_data;
-if (NULL == peasycap) {
-	SAY("ERROR in easyoss_read(): peasycap is NULL\n");
-	return -EFAULT;
-}
-if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
-	SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
-	return -EFAULT;
-}
-if (NULL == peasycap->pusb_device) {
-	SAY("ERROR: peasycap->pusb_device is NULL\n");
-	return -EFAULT;
-}
-kd = isdongle(peasycap);
-if (0 <= kd && DONGLE_MANY > kd) {
-	if (mutex_lock_interruptible(&(easycapdc60_dongle[kd].mutex_audio))) {
-		SAY("ERROR: "
-		"cannot lock easycapdc60_dongle[%i].mutex_audio\n", kd);
-		return -ERESTARTSYS;
-	}
-	JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd);
-/*---------------------------------------------------------------------------*/
-/*
- *  MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap,
- *  IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
- *  IF NECESSARY, BAIL OUT.
-*/
-/*---------------------------------------------------------------------------*/
-	if (kd != isdongle(peasycap))
-		return -ERESTARTSYS;
-	if (NULL == file) {
-		SAY("ERROR:  file is NULL\n");
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return -ERESTARTSYS;
-	}
-	peasycap = file->private_data;
-	if (NULL == peasycap) {
-		SAY("ERROR:  peasycap is NULL\n");
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return -ERESTARTSYS;
-	}
-	if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
-		SAY("ERROR: bad peasycap: 0x%08lX\n",
-						(unsigned long int) peasycap);
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return -ERESTARTSYS;
-	}
-	if (NULL == peasycap->pusb_device) {
-		SAM("ERROR: peasycap->pusb_device is NULL\n");
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return -ERESTARTSYS;
-	}
-} else {
-/*---------------------------------------------------------------------------*/
-/*
- *  IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE
- *  ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED.  BAIL OUT.
-*/
-/*---------------------------------------------------------------------------*/
-	return -ERESTARTSYS;
-}
-/*---------------------------------------------------------------------------*/
-if (file->f_flags & O_NONBLOCK)
-	JOT(16, "NONBLOCK  kount=%i, *poff=%i\n", (int)kount, (int)(*poff));
-else
-	JOT(8, "BLOCKING  kount=%i, *poff=%i\n", (int)kount, (int)(*poff));
-
-if ((0 > peasycap->audio_read) ||
-		(peasycap->audio_buffer_page_many <= peasycap->audio_read)) {
-	SAM("ERROR: peasycap->audio_read out of range\n");
-	mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-	return -EFAULT;
-}
-pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read];
-if ((struct data_buffer *)NULL == pdata_buffer) {
-	SAM("ERROR: pdata_buffer is NULL\n");
-	mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-	return -EFAULT;
-}
-JOM(12, "before wait, %i=frag read  %i=frag fill\n",
-		(peasycap->audio_read / peasycap->audio_pages_per_fragment),
-		(peasycap->audio_fill / peasycap->audio_pages_per_fragment));
-fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment);
-while ((fragment == (peasycap->audio_fill /
-				peasycap->audio_pages_per_fragment)) ||
-		(0 == (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))) {
-	if (file->f_flags & O_NONBLOCK) {
-		JOM(16, "returning -EAGAIN as instructed\n");
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return -EAGAIN;
-	}
-	rc = wait_event_interruptible(peasycap->wq_audio,
-		(peasycap->audio_idle  || peasycap->audio_eof   ||
-		((fragment != (peasycap->audio_fill /
-				peasycap->audio_pages_per_fragment)) &&
-		(0 < (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo))))));
-	if (0 != rc) {
-		SAM("aborted by signal\n");
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return -ERESTARTSYS;
-	}
-	if (peasycap->audio_eof) {
-		JOM(8, "returning 0 because  %i=audio_eof\n",
-							peasycap->audio_eof);
-		kill_audio_urbs(peasycap);
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return 0;
-	}
-	if (peasycap->audio_idle) {
-		JOM(16, "returning 0 because  %i=audio_idle\n",
-							peasycap->audio_idle);
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return 0;
-	}
-	if (!peasycap->audio_isoc_streaming) {
-		JOM(16, "returning 0 because audio urbs not streaming\n");
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return 0;
-	}
-}
-JOM(12, "after  wait, %i=frag read  %i=frag fill\n",
-		(peasycap->audio_read / peasycap->audio_pages_per_fragment),
-		(peasycap->audio_fill / peasycap->audio_pages_per_fragment));
-szret = (size_t)0;
-fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment);
-while (fragment == (peasycap->audio_read /
-				peasycap->audio_pages_per_fragment)) {
-	if (NULL == pdata_buffer->pgo) {
-		SAM("ERROR: pdata_buffer->pgo is NULL\n");
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return -EFAULT;
-	}
-	if (NULL == pdata_buffer->pto) {
-		SAM("ERROR: pdata_buffer->pto is NULL\n");
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return -EFAULT;
-	}
-	kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo);
-	if (0 > kount1) {
-		SAM("MISTAKE: kount1 is negative\n");
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return -ERESTARTSYS;
-	}
-	if (!kount1) {
-		(peasycap->audio_read)++;
-		if (peasycap->audio_buffer_page_many <= peasycap->audio_read)
-			peasycap->audio_read = 0;
-		JOM(12, "bumped peasycap->audio_read to %i\n",
-						peasycap->audio_read);
-
-		if (fragment != (peasycap->audio_read /
-					peasycap->audio_pages_per_fragment))
-			break;
-
-		if ((0 > peasycap->audio_read) ||
-			(peasycap->audio_buffer_page_many <=
-					peasycap->audio_read)) {
-			SAM("ERROR: peasycap->audio_read out of range\n");
-			mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-			return -EFAULT;
-		}
-		pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read];
-		if ((struct data_buffer *)NULL == pdata_buffer) {
-			SAM("ERROR: pdata_buffer is NULL\n");
-			mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-			return -EFAULT;
-		}
-		if (NULL == pdata_buffer->pgo) {
-			SAM("ERROR: pdata_buffer->pgo is NULL\n");
-			mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-			return -EFAULT;
-		}
-		if (NULL == pdata_buffer->pto) {
-			SAM("ERROR: pdata_buffer->pto is NULL\n");
-			mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-			return -EFAULT;
-		}
-		kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo);
-	}
-	JOM(12, "ready  to send %li bytes\n", (long int) kount1);
-	JOM(12, "still  to send %li bytes\n", (long int) kount);
-	more = kount1;
-	if (more > kount)
-		more = kount;
-	JOM(12, "agreed to send %li bytes from page %i\n",
-						more, peasycap->audio_read);
-	if (!more)
-		break;
-
-/*---------------------------------------------------------------------------*/
-/*
- *  ACCUMULATE DYNAMIC-RANGE INFORMATION
- */
-/*---------------------------------------------------------------------------*/
-	p0 = (unsigned char *)pdata_buffer->pgo;  l0 = 0;  lm = more/2;
-	while (l0 < lm) {
-		SUMMER(p0, &peasycap->audio_sample, &peasycap->audio_niveau,
-				&peasycap->audio_square);  l0++;  p0 += 2;
-	}
-/*---------------------------------------------------------------------------*/
-	rc = copy_to_user(puserspacebuffer, pdata_buffer->pto, more);
-	if (0 != rc) {
-		SAM("ERROR: copy_to_user() returned %li\n", rc);
-		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-		return -EFAULT;
-	}
-	*poff += (loff_t)more;
-	szret += (size_t)more;
-	pdata_buffer->pto += more;
-	puserspacebuffer += more;
-	kount -= (size_t)more;
-}
-JOM(12, "after  read, %i=frag read  %i=frag fill\n",
-		(peasycap->audio_read / peasycap->audio_pages_per_fragment),
-		(peasycap->audio_fill / peasycap->audio_pages_per_fragment));
-if (kount < 0) {
-	SAM("MISTAKE:  %li=kount  %li=szret\n",
-					(long int)kount, (long int)szret);
-}
-/*---------------------------------------------------------------------------*/
-/*
- *  CALCULATE DYNAMIC RANGE FOR (VAPOURWARE) AUTOMATIC VOLUME CONTROL
- */
-/*---------------------------------------------------------------------------*/
-if (peasycap->audio_sample) {
-	below = peasycap->audio_sample;
-	above = peasycap->audio_square;
-	sdr = signed_div(above, below);
-	above = sdr.quotient;
-	mean = peasycap->audio_niveau;
-	sdr = signed_div(mean, peasycap->audio_sample);
-
-	JOM(8, "%8lli=mean  %8lli=meansquare after %lli samples, =>\n",
-				sdr.quotient, above, peasycap->audio_sample);
-
-	sdr = signed_div(above, 32768);
-	JOM(8, "audio dynamic range is roughly %lli\n", sdr.quotient);
-}
-/*---------------------------------------------------------------------------*/
-/*
- *  UPDATE THE AUDIO CLOCK
- */
-/*---------------------------------------------------------------------------*/
-do_gettimeofday(&timeval);
-if (!peasycap->timeval1.tv_sec) {
-	peasycap->audio_bytes = 0;
-	peasycap->timeval3 = timeval;
-	peasycap->timeval1 = peasycap->timeval3;
-	sdr.quotient = 192000;
-} else {
-	peasycap->audio_bytes += (long long int) szret;
-	below = ((long long int)(1000000)) *
-		((long long int)(timeval.tv_sec  -
-						peasycap->timeval3.tv_sec)) +
-		(long long int)(timeval.tv_usec - peasycap->timeval3.tv_usec);
-	above = 1000000 * ((long long int) peasycap->audio_bytes);
-
-	if (below)
-		sdr = signed_div(above, below);
-	else
-		sdr.quotient = 192000;
-}
-JOM(8, "audio streaming at %lli bytes/second\n", sdr.quotient);
-peasycap->dnbydt = sdr.quotient;
-
-mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
-JOM(4, "unlocked easycapdc60_dongle[%i].mutex_audio\n", kd);
-JOM(8, "returning %li\n", (long int)szret);
-return szret;
-}
-/*****************************************************************************/
-
-#endif /*!EASYCAP_NEEDS_ALSA*/
+#endif /*! CONFIG_EASYCAP_OSS */
 
 /*****************************************************************************/
 /*****************************************************************************/
@@ -1484,11 +784,11 @@ if (!peasycap->audio_isoc_streaming) {
 					peasycap->audio_isoc_buffer[isbuf].pgo;
 				purb->transfer_buffer_length =
 					peasycap->audio_isoc_buffer_size;
-#if defined(EASYCAP_NEEDS_ALSA)
-				purb->complete = easycap_alsa_complete;
-#else
+#ifdef CONFIG_EASYCAP_OSS
 				purb->complete = easyoss_complete;
-#endif /*EASYCAP_NEEDS_ALSA*/
+#else /* CONFIG_EASYCAP_OSS */
+				purb->complete = easycap_alsa_complete;
+#endif /* CONFIG_EASYCAP_OSS */
 				purb->context = peasycap;
 				purb->start_frame = 0;
 				purb->number_of_packets =
diff --git a/drivers/staging/easycap/easycap_sound_oss.c b/drivers/staging/easycap/easycap_sound_oss.c
new file mode 100644
index 0000000..3f85cc3
--- /dev/null
+++ b/drivers/staging/easycap/easycap_sound_oss.c
@@ -0,0 +1,730 @@
+/******************************************************************************
+*                                                                             *
+*  easycap_sound.c                                                            *
+*                                                                             *
+*  Audio driver for EasyCAP USB2.0 Video Capture Device DC60                  *
+*                                                                             *
+*                                                                             *
+******************************************************************************/
+/*
+ *
+ *  Copyright (C) 2010 R.M. Thomas  <rmthomas at sciolus.org>
+ *
+ *
+ *  This 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.
+ *
+ *  The software 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this software; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+*/
+/*****************************************************************************/
+
+#include "easycap.h"
+
+/*****************************************************************************/
+/****************************                       **************************/
+/****************************   Open Sound System   **************************/
+/****************************                       **************************/
+/*****************************************************************************/
+/*--------------------------------------------------------------------------*/
+/*
+ *  PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE
+ */
+/*--------------------------------------------------------------------------*/
+const struct file_operations easyoss_fops = {
+	.owner		= THIS_MODULE,
+	.open		= easyoss_open,
+	.release	= easyoss_release,
+#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL)
+	.unlocked_ioctl	= easyoss_ioctl_noinode,
+#else
+	.ioctl		= easyoss_ioctl,
+#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/
+	.read		= easyoss_read,
+	.llseek		= no_llseek,
+};
+struct usb_class_driver easyoss_class = {
+.name = "usb/easyoss%d",
+.fops = &easyoss_fops,
+.minor_base = USB_SKEL_MINOR_BASE,
+};
+/*****************************************************************************/
+/*---------------------------------------------------------------------------*/
+/*
+ *  ON COMPLETION OF AN AUDIO URB ITS DATA IS COPIED TO THE AUDIO BUFFERS
+ *  PROVIDED peasycap->audio_idle IS ZERO.  REGARDLESS OF THIS BEING TRUE,
+ *  IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO.
+ */
+/*---------------------------------------------------------------------------*/
+void
+easyoss_complete(struct urb *purb)
+{
+struct easycap *peasycap;
+struct data_buffer *paudio_buffer;
+__u8 *p1, *p2;
+__s16 s16;
+int i, j, more, much, leap, rc;
+#if defined(UPSAMPLE)
+int k;
+__s16 oldaudio, newaudio, delta;
+#endif /*UPSAMPLE*/
+
+JOT(16, "\n");
+
+if (NULL == purb) {
+	SAY("ERROR: purb is NULL\n");
+	return;
+}
+peasycap = purb->context;
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
+	return;
+}
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	SAY("ERROR: bad peasycap\n");
+	return;
+}
+much = 0;
+if (peasycap->audio_idle) {
+	JOM(16, "%i=audio_idle  %i=audio_isoc_streaming\n",
+			peasycap->audio_idle, peasycap->audio_isoc_streaming);
+	if (peasycap->audio_isoc_streaming) {
+		rc = usb_submit_urb(purb, GFP_ATOMIC);
+		if (rc) {
+			if (-ENODEV != rc && -ENOENT != rc) {
+				SAM("ERROR: while %i=audio_idle, "
+				    "usb_submit_urb() failed with rc: -%s: %d\n",
+					peasycap->audio_idle,
+					strerror(rc), rc);
+			}
+		}
+	}
+return;
+}
+/*---------------------------------------------------------------------------*/
+if (purb->status) {
+	if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) {
+		JOM(16, "urb status -ESHUTDOWN or -ENOENT\n");
+		return;
+	}
+	SAM("ERROR: non-zero urb status: -%s: %d\n",
+		strerror(purb->status), purb->status);
+	goto resubmit;
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  PROCEED HERE WHEN NO ERROR
+ */
+/*---------------------------------------------------------------------------*/
+#if defined(UPSAMPLE)
+oldaudio = peasycap->oldaudio;
+#endif /*UPSAMPLE*/
+
+for (i = 0;  i < purb->number_of_packets; i++) {
+	if (!purb->iso_frame_desc[i].status) {
+
+		SAM("-%s\n", strerror(purb->iso_frame_desc[i].status));
+
+		more = purb->iso_frame_desc[i].actual_length;
+
+#if defined(TESTTONE)
+		if (!more)
+			more = purb->iso_frame_desc[i].length;
+#endif
+
+		if (!more)
+			peasycap->audio_mt++;
+		else {
+			if (peasycap->audio_mt) {
+				JOM(12, "%4i empty audio urb frames\n",
+							peasycap->audio_mt);
+				peasycap->audio_mt = 0;
+			}
+
+			p1 = (__u8 *)(purb->transfer_buffer +
+					purb->iso_frame_desc[i].offset);
+
+			leap = 0;
+			p1 += leap;
+			more -= leap;
+/*---------------------------------------------------------------------------*/
+/*
+ *  COPY more BYTES FROM ISOC BUFFER TO AUDIO BUFFER,
+ *  CONVERTING 8-BIT MONO TO 16-BIT SIGNED LITTLE-ENDIAN SAMPLES IF NECESSARY
+ */
+/*---------------------------------------------------------------------------*/
+			while (more) {
+				if (0 > more) {
+					SAM("MISTAKE: more is negative\n");
+					return;
+				}
+				if (peasycap->audio_buffer_page_many <=
+							peasycap->audio_fill) {
+					SAM("ERROR: bad "
+						"peasycap->audio_fill\n");
+					return;
+				}
+
+				paudio_buffer = &peasycap->audio_buffer
+							[peasycap->audio_fill];
+				if (PAGE_SIZE < (paudio_buffer->pto -
+						paudio_buffer->pgo)) {
+					SAM("ERROR: bad paudio_buffer->pto\n");
+					return;
+				}
+				if (PAGE_SIZE == (paudio_buffer->pto -
+							paudio_buffer->pgo)) {
+
+#if defined(TESTTONE)
+					easyoss_testtone(peasycap,
+							peasycap->audio_fill);
+#endif /*TESTTONE*/
+
+					paudio_buffer->pto =
+							paudio_buffer->pgo;
+					(peasycap->audio_fill)++;
+					if (peasycap->
+						audio_buffer_page_many <=
+							peasycap->audio_fill)
+						peasycap->audio_fill = 0;
+
+					JOM(8, "bumped peasycap->"
+							"audio_fill to %i\n",
+							peasycap->audio_fill);
+
+					paudio_buffer = &peasycap->
+							audio_buffer
+							[peasycap->audio_fill];
+					paudio_buffer->pto =
+							paudio_buffer->pgo;
+
+					if (!(peasycap->audio_fill %
+						peasycap->
+						audio_pages_per_fragment)) {
+						JOM(12, "wakeup call on wq_"
+						"audio, %i=frag reading  %i"
+						"=fragment fill\n",
+						(peasycap->audio_read /
+						peasycap->
+						audio_pages_per_fragment),
+						(peasycap->audio_fill /
+						peasycap->
+						audio_pages_per_fragment));
+						wake_up_interruptible
+						(&(peasycap->wq_audio));
+					}
+				}
+
+				much = PAGE_SIZE - (int)(paudio_buffer->pto -
+							 paudio_buffer->pgo);
+
+				if (false == peasycap->microphone) {
+					if (much > more)
+						much = more;
+
+					memcpy(paudio_buffer->pto, p1, much);
+					p1 += much;
+					more -= much;
+				} else {
+#if defined(UPSAMPLE)
+					if (much % 16)
+						JOM(8, "MISTAKE? much"
+						" is not divisible by 16\n");
+					if (much > (16 *
+							more))
+						much = 16 *
+							more;
+					p2 = (__u8 *)paudio_buffer->pto;
+
+					for (j = 0;  j < (much/16);  j++) {
+						newaudio =  ((int) *p1) - 128;
+						newaudio = 128 *
+								newaudio;
+
+						delta = (newaudio - oldaudio)
+									/ 4;
+						s16 = oldaudio + delta;
+
+						for (k = 0;  k < 4;  k++) {
+							*p2 = (0x00FF & s16);
+							*(p2 + 1) = (0xFF00 &
+								s16) >> 8;
+							p2 += 2;
+							*p2 = (0x00FF & s16);
+							*(p2 + 1) = (0xFF00 &
+								s16) >> 8;
+							p2 += 2;
+
+							s16 += delta;
+						}
+						p1++;
+						more--;
+						oldaudio = s16;
+					}
+#else /*!UPSAMPLE*/
+					if (much > (2 * more))
+						much = 2 * more;
+					p2 = (__u8 *)paudio_buffer->pto;
+
+					for (j = 0;  j < (much / 2);  j++) {
+						s16 =  ((int) *p1) - 128;
+						s16 = 128 *
+								s16;
+						*p2 = (0x00FF & s16);
+						*(p2 + 1) = (0xFF00 & s16) >>
+									8;
+						p1++;  p2 += 2;
+						more--;
+					}
+#endif /*UPSAMPLE*/
+				}
+				(paudio_buffer->pto) += much;
+			}
+		}
+	} else {
+		JOM(12, "discarding audio samples because "
+			"%i=purb->iso_frame_desc[i].status\n",
+				purb->iso_frame_desc[i].status);
+	}
+
+#if defined(UPSAMPLE)
+peasycap->oldaudio = oldaudio;
+#endif /*UPSAMPLE*/
+
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  RESUBMIT THIS URB
+ */
+/*---------------------------------------------------------------------------*/
+resubmit:
+if (peasycap->audio_isoc_streaming) {
+	rc = usb_submit_urb(purb, GFP_ATOMIC);
+	if (0 != rc) {
+		if (-ENODEV != rc && -ENOENT != rc) {
+			SAM("ERROR: while %i=audio_idle, "
+				"usb_submit_urb() failed "
+				"with rc: -%s: %d\n", peasycap->audio_idle,
+				strerror(rc), rc);
+		}
+	}
+}
+return;
+}
+/*****************************************************************************/
+/*---------------------------------------------------------------------------*/
+/*
+ *  THE AUDIO URBS ARE SUBMITTED AT THIS EARLY STAGE SO THAT IT IS POSSIBLE TO
+ *  STREAM FROM /dev/easyoss1 WITH SIMPLE PROGRAMS SUCH AS cat WHICH DO NOT
+ *  HAVE AN IOCTL INTERFACE.
+ */
+/*---------------------------------------------------------------------------*/
+int
+easyoss_open(struct inode *inode, struct file *file)
+{
+struct usb_interface *pusb_interface;
+struct easycap *peasycap;
+int subminor;
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
+#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
+struct v4l2_device *pv4l2_device;
+#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+
+JOT(4, "begins\n");
+
+subminor = iminor(inode);
+
+pusb_interface = usb_find_interface(&easycap_usb_driver, subminor);
+if (NULL == pusb_interface) {
+	SAY("ERROR: pusb_interface is NULL\n");
+	SAY("ending unsuccessfully\n");
+	return -1;
+}
+peasycap = usb_get_intfdata(pusb_interface);
+if (NULL == peasycap) {
+	SAY("ERROR: peasycap is NULL\n");
+	SAY("ending unsuccessfully\n");
+	return -1;
+}
+/*---------------------------------------------------------------------------*/
+#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT))
+#
+/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
+#else
+#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
+/*---------------------------------------------------------------------------*/
+/*
+ *  SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS
+ *  BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(),
+ *  REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE.
+ *  TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED.
+*/
+/*---------------------------------------------------------------------------*/
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	pv4l2_device = usb_get_intfdata(pusb_interface);
+	if ((struct v4l2_device *)NULL == pv4l2_device) {
+		SAY("ERROR: pv4l2_device is NULL\n");
+		return -EFAULT;
+	}
+	peasycap = (struct easycap *)
+		container_of(pv4l2_device, struct easycap, v4l2_device);
+}
+#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
+#
+#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
+/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
+/*---------------------------------------------------------------------------*/
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
+	return -EFAULT;
+}
+/*---------------------------------------------------------------------------*/
+
+file->private_data = peasycap;
+
+if (0 != easycap_sound_setup(peasycap)) {
+	;
+	;
+}
+return 0;
+}
+/*****************************************************************************/
+int
+easyoss_release(struct inode *inode, struct file *file)
+{
+struct easycap *peasycap;
+
+JOT(4, "begins\n");
+
+peasycap = file->private_data;
+if (NULL == peasycap) {
+	SAY("ERROR:  peasycap is NULL.\n");
+	return -EFAULT;
+}
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
+	return -EFAULT;
+}
+if (0 != kill_audio_urbs(peasycap)) {
+	SAM("ERROR: kill_audio_urbs() failed\n");
+	return -EFAULT;
+}
+JOM(4, "ending successfully\n");
+return 0;
+}
+/*****************************************************************************/
+ssize_t
+easyoss_read(struct file *file, char __user *puserspacebuffer,
+						size_t kount, loff_t *poff)
+{
+struct timeval timeval;
+long long int above, below, mean;
+struct signed_div_result sdr;
+unsigned char *p0;
+long int kount1, more, rc, l0, lm;
+int fragment, kd;
+struct easycap *peasycap;
+struct data_buffer *pdata_buffer;
+size_t szret;
+
+/*---------------------------------------------------------------------------*/
+/*
+ *  DO A BLOCKING READ TO TRANSFER DATA TO USER SPACE.
+ *
+ ******************************************************************************
+ *****  N.B.  IF THIS FUNCTION RETURNS 0, NOTHING IS SEEN IN USER SPACE. ******
+ *****        THIS CONDITION SIGNIFIES END-OF-FILE.                      ******
+ ******************************************************************************
+ */
+/*---------------------------------------------------------------------------*/
+
+JOT(8, "%5i=kount  %5i=*poff\n", (int)kount, (int)(*poff));
+
+if (NULL == file) {
+	SAY("ERROR:  file is NULL\n");
+	return -ERESTARTSYS;
+}
+peasycap = file->private_data;
+if (NULL == peasycap) {
+	SAY("ERROR in easyoss_read(): peasycap is NULL\n");
+	return -EFAULT;
+}
+if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+	SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap);
+	return -EFAULT;
+}
+if (NULL == peasycap->pusb_device) {
+	SAY("ERROR: peasycap->pusb_device is NULL\n");
+	return -EFAULT;
+}
+kd = isdongle(peasycap);
+if (0 <= kd && DONGLE_MANY > kd) {
+	if (mutex_lock_interruptible(&(easycapdc60_dongle[kd].mutex_audio))) {
+		SAY("ERROR: "
+		"cannot lock easycapdc60_dongle[%i].mutex_audio\n", kd);
+		return -ERESTARTSYS;
+	}
+	JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd);
+/*---------------------------------------------------------------------------*/
+/*
+ *  MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap,
+ *  IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
+ *  IF NECESSARY, BAIL OUT.
+*/
+/*---------------------------------------------------------------------------*/
+	if (kd != isdongle(peasycap))
+		return -ERESTARTSYS;
+	if (NULL == file) {
+		SAY("ERROR:  file is NULL\n");
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return -ERESTARTSYS;
+	}
+	peasycap = file->private_data;
+	if (NULL == peasycap) {
+		SAY("ERROR:  peasycap is NULL\n");
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return -ERESTARTSYS;
+	}
+	if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
+		SAY("ERROR: bad peasycap: 0x%08lX\n",
+						(unsigned long int) peasycap);
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return -ERESTARTSYS;
+	}
+	if (NULL == peasycap->pusb_device) {
+		SAM("ERROR: peasycap->pusb_device is NULL\n");
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return -ERESTARTSYS;
+	}
+} else {
+/*---------------------------------------------------------------------------*/
+/*
+ *  IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE
+ *  ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED.  BAIL OUT.
+*/
+/*---------------------------------------------------------------------------*/
+	return -ERESTARTSYS;
+}
+/*---------------------------------------------------------------------------*/
+if (file->f_flags & O_NONBLOCK)
+	JOT(16, "NONBLOCK  kount=%i, *poff=%i\n", (int)kount, (int)(*poff));
+else
+	JOT(8, "BLOCKING  kount=%i, *poff=%i\n", (int)kount, (int)(*poff));
+
+if ((0 > peasycap->audio_read) ||
+		(peasycap->audio_buffer_page_many <= peasycap->audio_read)) {
+	SAM("ERROR: peasycap->audio_read out of range\n");
+	mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+	return -EFAULT;
+}
+pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read];
+if ((struct data_buffer *)NULL == pdata_buffer) {
+	SAM("ERROR: pdata_buffer is NULL\n");
+	mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+	return -EFAULT;
+}
+JOM(12, "before wait, %i=frag read  %i=frag fill\n",
+		(peasycap->audio_read / peasycap->audio_pages_per_fragment),
+		(peasycap->audio_fill / peasycap->audio_pages_per_fragment));
+fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment);
+while ((fragment == (peasycap->audio_fill /
+				peasycap->audio_pages_per_fragment)) ||
+		(0 == (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))) {
+	if (file->f_flags & O_NONBLOCK) {
+		JOM(16, "returning -EAGAIN as instructed\n");
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return -EAGAIN;
+	}
+	rc = wait_event_interruptible(peasycap->wq_audio,
+		(peasycap->audio_idle  || peasycap->audio_eof   ||
+		((fragment != (peasycap->audio_fill /
+				peasycap->audio_pages_per_fragment)) &&
+		(0 < (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo))))));
+	if (0 != rc) {
+		SAM("aborted by signal\n");
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return -ERESTARTSYS;
+	}
+	if (peasycap->audio_eof) {
+		JOM(8, "returning 0 because  %i=audio_eof\n",
+							peasycap->audio_eof);
+		kill_audio_urbs(peasycap);
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return 0;
+	}
+	if (peasycap->audio_idle) {
+		JOM(16, "returning 0 because  %i=audio_idle\n",
+							peasycap->audio_idle);
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return 0;
+	}
+	if (!peasycap->audio_isoc_streaming) {
+		JOM(16, "returning 0 because audio urbs not streaming\n");
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return 0;
+	}
+}
+JOM(12, "after  wait, %i=frag read  %i=frag fill\n",
+		(peasycap->audio_read / peasycap->audio_pages_per_fragment),
+		(peasycap->audio_fill / peasycap->audio_pages_per_fragment));
+szret = (size_t)0;
+fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment);
+while (fragment == (peasycap->audio_read /
+				peasycap->audio_pages_per_fragment)) {
+	if (NULL == pdata_buffer->pgo) {
+		SAM("ERROR: pdata_buffer->pgo is NULL\n");
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return -EFAULT;
+	}
+	if (NULL == pdata_buffer->pto) {
+		SAM("ERROR: pdata_buffer->pto is NULL\n");
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return -EFAULT;
+	}
+	kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo);
+	if (0 > kount1) {
+		SAM("MISTAKE: kount1 is negative\n");
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return -ERESTARTSYS;
+	}
+	if (!kount1) {
+		(peasycap->audio_read)++;
+		if (peasycap->audio_buffer_page_many <= peasycap->audio_read)
+			peasycap->audio_read = 0;
+		JOM(12, "bumped peasycap->audio_read to %i\n",
+						peasycap->audio_read);
+
+		if (fragment != (peasycap->audio_read /
+					peasycap->audio_pages_per_fragment))
+			break;
+
+		if ((0 > peasycap->audio_read) ||
+			(peasycap->audio_buffer_page_many <=
+					peasycap->audio_read)) {
+			SAM("ERROR: peasycap->audio_read out of range\n");
+			mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+			return -EFAULT;
+		}
+		pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read];
+		if ((struct data_buffer *)NULL == pdata_buffer) {
+			SAM("ERROR: pdata_buffer is NULL\n");
+			mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+			return -EFAULT;
+		}
+		if (NULL == pdata_buffer->pgo) {
+			SAM("ERROR: pdata_buffer->pgo is NULL\n");
+			mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+			return -EFAULT;
+		}
+		if (NULL == pdata_buffer->pto) {
+			SAM("ERROR: pdata_buffer->pto is NULL\n");
+			mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+			return -EFAULT;
+		}
+		kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo);
+	}
+	JOM(12, "ready  to send %li bytes\n", (long int) kount1);
+	JOM(12, "still  to send %li bytes\n", (long int) kount);
+	more = kount1;
+	if (more > kount)
+		more = kount;
+	JOM(12, "agreed to send %li bytes from page %i\n",
+						more, peasycap->audio_read);
+	if (!more)
+		break;
+
+/*---------------------------------------------------------------------------*/
+/*
+ *  ACCUMULATE DYNAMIC-RANGE INFORMATION
+ */
+/*---------------------------------------------------------------------------*/
+	p0 = (unsigned char *)pdata_buffer->pgo;  l0 = 0;  lm = more/2;
+	while (l0 < lm) {
+		SUMMER(p0, &peasycap->audio_sample, &peasycap->audio_niveau,
+				&peasycap->audio_square);  l0++;  p0 += 2;
+	}
+/*---------------------------------------------------------------------------*/
+	rc = copy_to_user(puserspacebuffer, pdata_buffer->pto, more);
+	if (0 != rc) {
+		SAM("ERROR: copy_to_user() returned %li\n", rc);
+		mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+		return -EFAULT;
+	}
+	*poff += (loff_t)more;
+	szret += (size_t)more;
+	pdata_buffer->pto += more;
+	puserspacebuffer += more;
+	kount -= (size_t)more;
+}
+JOM(12, "after  read, %i=frag read  %i=frag fill\n",
+		(peasycap->audio_read / peasycap->audio_pages_per_fragment),
+		(peasycap->audio_fill / peasycap->audio_pages_per_fragment));
+if (kount < 0) {
+	SAM("MISTAKE:  %li=kount  %li=szret\n",
+					(long int)kount, (long int)szret);
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  CALCULATE DYNAMIC RANGE FOR (VAPOURWARE) AUTOMATIC VOLUME CONTROL
+ */
+/*---------------------------------------------------------------------------*/
+if (peasycap->audio_sample) {
+	below = peasycap->audio_sample;
+	above = peasycap->audio_square;
+	sdr = signed_div(above, below);
+	above = sdr.quotient;
+	mean = peasycap->audio_niveau;
+	sdr = signed_div(mean, peasycap->audio_sample);
+
+	JOM(8, "%8lli=mean  %8lli=meansquare after %lli samples, =>\n",
+				sdr.quotient, above, peasycap->audio_sample);
+
+	sdr = signed_div(above, 32768);
+	JOM(8, "audio dynamic range is roughly %lli\n", sdr.quotient);
+}
+/*---------------------------------------------------------------------------*/
+/*
+ *  UPDATE THE AUDIO CLOCK
+ */
+/*---------------------------------------------------------------------------*/
+do_gettimeofday(&timeval);
+if (!peasycap->timeval1.tv_sec) {
+	peasycap->audio_bytes = 0;
+	peasycap->timeval3 = timeval;
+	peasycap->timeval1 = peasycap->timeval3;
+	sdr.quotient = 192000;
+} else {
+	peasycap->audio_bytes += (long long int) szret;
+	below = ((long long int)(1000000)) *
+		((long long int)(timeval.tv_sec  -
+						peasycap->timeval3.tv_sec)) +
+		(long long int)(timeval.tv_usec - peasycap->timeval3.tv_usec);
+	above = 1000000 * ((long long int) peasycap->audio_bytes);
+
+	if (below)
+		sdr = signed_div(above, below);
+	else
+		sdr.quotient = 192000;
+}
+JOM(8, "audio streaming at %lli bytes/second\n", sdr.quotient);
+peasycap->dnbydt = sdr.quotient;
+
+mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
+JOM(4, "unlocked easycapdc60_dongle[%i].mutex_audio\n", kd);
+JOM(8, "returning %li\n", (long int)szret);
+return szret;
+}
+/*****************************************************************************/
+
-- 
1.7.3.4

---------------------------------------------------------------------
Intel Israel (74) Limited

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.




More information about the devel mailing list