diff options
Diffstat (limited to 'audio/alsa-plugins/files/patch-oss_pcm__oss.c')
-rw-r--r-- | audio/alsa-plugins/files/patch-oss_pcm__oss.c | 129 |
1 files changed, 126 insertions, 3 deletions
diff --git a/audio/alsa-plugins/files/patch-oss_pcm__oss.c b/audio/alsa-plugins/files/patch-oss_pcm__oss.c index 79966ae29fb8..ab9d39d01951 100644 --- a/audio/alsa-plugins/files/patch-oss_pcm__oss.c +++ b/audio/alsa-plugins/files/patch-oss_pcm__oss.c @@ -1,4 +1,4 @@ ---- oss/pcm_oss.c.orig 2016-07-26 13:27:23 UTC +--- oss/pcm_oss.c.orig 2019-07-04 14:37:07 UTC +++ oss/pcm_oss.c @@ -22,7 +22,11 @@ #include <sys/ioctl.h> @@ -12,7 +12,55 @@ #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) -@@ -258,7 +262,7 @@ static int oss_drain(snd_pcm_ioplug_t *i +@@ -74,11 +78,19 @@ static snd_pcm_sframes_t oss_write(snd_p + size *= oss->frame_bytes; + result = write(oss->fd, buf, size); + #ifdef __FreeBSD__ +- if (result == -1) +- return -errno; ++ if (result == -1) { ++ if (errno == EAGAIN) ++ return 0; ++ else ++ return -errno; ++ } + #else +- if (result <= 0) +- return result; ++ if (result <= 0) { ++ if (result == -EAGAIN) ++ return 0; ++ else ++ return result; ++ } + #endif + return result / oss->frame_bytes; + } +@@ -97,11 +109,19 @@ static snd_pcm_sframes_t oss_read(snd_pc + size *= oss->frame_bytes; + result = read(oss->fd, buf, size); + #ifdef __FreeBSD__ +- if (result == -1) +- return -errno; ++ if (result == -1) { ++ if (errno == EAGAIN) ++ return 0; ++ else ++ return -errno; ++ } + #else +- if (result <= 0) +- return result; ++ if (result <= 0) { ++ if (result == -EAGAIN) ++ return 0; ++ else ++ return result; ++ } + #endif + return result / oss->frame_bytes; + } +@@ -258,10 +278,29 @@ static int oss_drain(snd_pcm_ioplug_t *i #endif if (io->stream == SND_PCM_STREAM_PLAYBACK) @@ -21,7 +69,29 @@ return 0; } -@@ -272,7 +276,7 @@ static int oss_prepare(snd_pcm_ioplug_t ++static int oss_delay(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delayp) ++{ ++ snd_pcm_oss_t *oss = io->private_data; ++ int tmp; ++ ++ if (oss->fd < 0) ++ return -EBADFD; ++ ++ if (io->stream == SND_PCM_STREAM_PLAYBACK) { ++ if (ioctl(oss->fd, SNDCTL_DSP_GETODELAY, &tmp) < 0 || tmp < 0) ++ tmp = 0; ++ } else { ++ tmp = 0; ++ } ++ *delayp = snd_pcm_bytes_to_frames(io->pcm, tmp); ++ ++ return (0); ++} ++ + #ifndef __FreeBSD__ + static int oss_prepare(snd_pcm_ioplug_t *io) + { +@@ -272,7 +311,7 @@ static int oss_prepare(snd_pcm_ioplug_t fprintf(stderr, "%s()\n", __func__); #endif @@ -30,3 +100,56 @@ tmp = io->channels; if (ioctl(oss->fd, SNDCTL_DSP_CHANNELS, &tmp) < 0) { +@@ -380,20 +419,26 @@ static int oss_hw_params(snd_pcm_ioplug_ + + ioctl(oss->fd, SNDCTL_DSP_RESET); + +-#define blksz_aligned() ((1 << blksz_shift) - \ +- ((1 << blksz_shift) % oss->frame_bytes)) +- blksz_shift = 16; +- tmp = io->period_size * oss->frame_bytes; ++ /* use a 16ms HW buffer by default */ ++ tmp = ((16 * io->rate) / 1000) * oss->frame_bytes; + +- while (blksz_shift > 4 && blksz_aligned() > tmp) +- blksz_shift--; ++ /* round up to nearest power of two */ ++ while (tmp & (tmp - 1)) ++ tmp += tmp & ~(tmp - 1); ++ ++ /* get logarithmic value */ ++ for (blksz_shift = 0; blksz_shift < 24; blksz_shift++) { ++ if (tmp == (1 << blksz_shift)) ++ break; ++ } + +- blkcnt = 2; + tmp = io->buffer_size * oss->frame_bytes; + +- while (blkcnt < 4096 && (blksz_aligned() * blkcnt) < tmp && +- ((1 << blksz_shift) * blkcnt) < 131072) +- blkcnt <<= 1; ++ /* compute HW buffer big enough to hold SW buffer */ ++ for (blkcnt = FREEBSD_OSS_BLKCNT_MIN; blkcnt != FREEBSD_OSS_BLKCNT_MAX; blkcnt *= 2) { ++ if ((blkcnt << blksz_shift) >= tmp) ++ break; ++ } + + tmp = blksz_shift | (blkcnt << 16); + if (ioctl(oss->fd, SNDCTL_DSP_SETFRAGMENT, &tmp) < 0) { +@@ -767,6 +812,7 @@ static const snd_pcm_ioplug_callback_t o + .prepare = oss_prepare, + #endif + .drain = oss_drain, ++ .delay = oss_delay, + }; + + static const snd_pcm_ioplug_callback_t oss_capture_callback = { +@@ -780,6 +826,7 @@ static const snd_pcm_ioplug_callback_t o + .prepare = oss_prepare, + #endif + .drain = oss_drain, ++ .delay = oss_delay, + }; + + |