On Mon, Nov 22, 2021 at 10:00:13PM +0000, nia wrote:
> On Mon, Nov 22, 2021 at 12:02:36PM +0100, Hauke Fath wrote:
> > As a data point, an attempt to record 10 seconds through alsa will hang 
> > indefinitely, and leave an empty file stub:
> 
> It is repeatedly using SNDCTL_DSP_GETIPTR, which is a wrapper around
> AUDIO_GETIOFFS, which is unimplemented in isaki-audio2, so always
> returns 0 (indicating that no frames are available to read). So
> it assumes that it can't read anything.
> 
> https://nxr.netbsd.org/xref/src/sys/dev/audio/audio.c#3031
> 
> I'll have to think about this.

I have two patches for you to try. One implements AUDIO_GETIOFFS
in the kernel, the other works around alsa-plugins-oss's abuse
of non-blocking I/O. With both patches, I get crystal clear
recording with arecord.

Index: audio.c
===================================================================
RCS file: /cvsroot/src/sys/dev/audio/audio.c,v
retrieving revision 1.110
diff -u -p -u -r1.110 audio.c
--- audio.c     10 Oct 2021 11:21:05 -0000      1.110
+++ audio.c     23 Nov 2021 00:06:33 -0000
@@ -3029,16 +3029,10 @@ audio_ioctl(dev_t dev, struct audio_soft
                break;
 
        case AUDIO_GETIOFFS:
-               /* XXX TODO */
-               ao = (struct audio_offset *)addr;
-               ao->samples = 0;
-               ao->deltablks = 0;
-               ao->offset = 0;
-               break;
-
        case AUDIO_GETOOFFS:
                ao = (struct audio_offset *)addr;
-               track = file->ptrack;
+               track = (cmd == AUDIO_GETOOFFS) ?
+                   file->ptrack : file->rtrack;
                if (track == NULL) {
                        ao->samples = 0;
                        ao->deltablks = 0;
@@ -3063,7 +3057,9 @@ audio_ioctl(dev_t dev, struct audio_soft
                        offs -= track->usrbuf.capacity;
                ao->offset = offs;
 
-               TRACET(3, track, "GETOOFFS: samples=%u deltablks=%u offset=%u",
+               TRACET(3, track, "%s: samples=%u deltablks=%u offset=%u",
+                   (cmd == AUDIO_GETOOFS) ?
+                       "AUDIO_GETOOFFS" : "AUDIO_GETIOFFS",
                    ao->samples, ao->deltablks, ao->offset);
                break;
 
? alsa-plugins-oss/recording.wav
? alsa-plugins-oss/test.wav
? alsa-plugins-oss/work
Index: alsa-plugins-oss/Makefile
===================================================================
RCS file: /cvsroot/pkgsrc/audio/alsa-plugins-oss/Makefile,v
retrieving revision 1.14
diff -u -p -u -r1.14 Makefile
--- alsa-plugins-oss/Makefile   30 Jun 2021 15:41:54 -0000      1.14
+++ alsa-plugins-oss/Makefile   23 Nov 2021 00:06:16 -0000
@@ -2,6 +2,7 @@
 
 DISTNAME=      alsa-plugins-1.2.5
 PKGNAME=       ${DISTNAME:S/plugins/plugins-oss/}
+PKGREVISION=   1
 CATEGORIES=    audio
 MASTER_SITES=  ftp://ftp.alsa-project.org/pub/plugins/
 EXTRACT_SUFX=  .tar.bz2
Index: alsa-plugins-oss/distinfo
===================================================================
RCS file: /cvsroot/pkgsrc/audio/alsa-plugins-oss/distinfo,v
retrieving revision 1.12
diff -u -p -u -r1.12 distinfo
--- alsa-plugins-oss/distinfo   26 Oct 2021 09:58:46 -0000      1.12
+++ alsa-plugins-oss/distinfo   23 Nov 2021 00:06:16 -0000
@@ -5,5 +5,5 @@ SHA512 (alsa-plugins-1.2.5.tar.bz2) = 32
 Size (alsa-plugins-1.2.5.tar.bz2) = 406134 bytes
 SHA1 (patch-aa) = ac2169b0a069bcf6ed60ca7ccd199ccd1988357f
 SHA1 (patch-ab) = 9cf0bda9f1928f46d0d5eac9464b790710ea2fda
-SHA1 (patch-ac) = 13da103ce3daad29d3c715f8f7d58dcd7bb9a72c
+SHA1 (patch-ac) = e1a66677909e0d9b210aba0de65ae2222728d6f5
 SHA1 (patch-oss_Makefile.in) = 9ca6c96d426f7f150c86ad7a3a15fa0999a3cfdd
Index: alsa-plugins-oss/patches/patch-ac
===================================================================
RCS file: /cvsroot/pkgsrc/audio/alsa-plugins-oss/patches/patch-ac,v
retrieving revision 1.1.1.1
diff -u -p -u -r1.1.1.1 patch-ac
--- alsa-plugins-oss/patches/patch-ac   19 Dec 2008 04:03:22 -0000      1.1.1.1
+++ alsa-plugins-oss/patches/patch-ac   23 Nov 2021 00:06:16 -0000
@@ -1,6 +1,6 @@
 $NetBSD: patch-ac,v 1.1.1.1 2008/12/19 04:03:22 jmcneill Exp $
 
---- oss/pcm_oss.c.orig 2008-10-29 08:42:13.000000000 -0400
+--- oss/pcm_oss.c.orig 2021-05-27 17:18:39.000000000 +0000
 +++ oss/pcm_oss.c
 @@ -22,7 +22,11 @@
  #include <sys/ioctl.h>
@@ -14,7 +14,35 @@ $NetBSD: patch-ac,v 1.1.1.1 2008/12/19 0
  
  typedef struct snd_pcm_oss {
        snd_pcm_ioplug_t io;
-@@ -116,7 +120,7 @@ static int oss_drain(snd_pcm_ioplug_t *i
+@@ -49,8 +53,11 @@ static snd_pcm_sframes_t oss_write(snd_p
+       buf = (char *)areas->addr + (areas->first + areas->step * offset) / 8;
+       size *= oss->frame_bytes;
+       result = write(oss->fd, buf, size);
+-      if (result <= 0)
++      if (result <= 0) {
++              if (errno == EAGAIN || errno == EWOULDBLOCK)
++                      return 0;
+               return result;
++      }
+       return result / oss->frame_bytes;
+ }
+ 
+@@ -66,9 +73,13 @@ static snd_pcm_sframes_t oss_read(snd_pc
+       /* we handle only an interleaved buffer */
+       buf = (char *)areas->addr + (areas->first + areas->step * offset) / 8;
+       size *= oss->frame_bytes;
++      errno = 0;
+       result = read(oss->fd, buf, size);
+-      if (result <= 0)
++      if (result <= 0) {
++              if (errno == EAGAIN || errno == EWOULDBLOCK)
++                      return 0;
+               return result;
++      }
+       return result / oss->frame_bytes;
+ }
+ 
+@@ -116,7 +127,7 @@ static int oss_drain(snd_pcm_ioplug_t *i
        snd_pcm_oss_t *oss = io->private_data;
  
        if (io->stream == SND_PCM_STREAM_PLAYBACK)
@@ -23,7 +51,7 @@ $NetBSD: patch-ac,v 1.1.1.1 2008/12/19 0
        return 0;
  }
  
-@@ -125,7 +129,7 @@ static int oss_prepare(snd_pcm_ioplug_t 
+@@ -125,7 +136,7 @@ static int oss_prepare(snd_pcm_ioplug_t 
        snd_pcm_oss_t *oss = io->private_data;
        int tmp;
  
@@ -32,7 +60,23 @@ $NetBSD: patch-ac,v 1.1.1.1 2008/12/19 0
  
        tmp = io->channels;
        if (ioctl(oss->fd, SNDCTL_DSP_CHANNELS, &tmp) < 0) {
-@@ -355,7 +359,7 @@ static snd_pcm_ioplug_callback_t oss_cap
+@@ -210,6 +221,7 @@ static int oss_hw_params(snd_pcm_ioplug_
+       }
+       oss->fragment_set = 1;
+ 
++#ifndef __NetBSD__
+       if ((flags = fcntl(oss->fd, F_GETFL)) < 0) {
+               err = -errno;
+               perror("F_GETFL");
+@@ -225,6 +237,7 @@ static int oss_hw_params(snd_pcm_ioplug_
+                       perror("F_SETFL");
+               }
+       }
++#endif
+ 
+       return 0;
+ }
+@@ -356,7 +369,7 @@ static const snd_pcm_ioplug_callback_t o
  SND_PCM_PLUGIN_DEFINE_FUNC(oss)
  {
        snd_config_iterator_t i, next;

Reply via email to