commit:     db98333db476343854d4abf5cfe7c86a6f802399
Author:     William Hubbs <williamh <AT> gentoo <DOT> org>
AuthorDate: Fri Sep  9 05:10:27 2022 +0000
Commit:     William Hubbs <williamh <AT> gentoo <DOT> org>
CommitDate: Fri Sep  9 05:13:13 2022 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=db98333d

media-libs/pcaudiolib: 1.2-r1 revbump

update EAPI 7 -> 8
add patches from the bug.

Bug: https://bugs.gentoo.org/867793
Signed-off-by: William Hubbs <williamh <AT> gentoo.org>

 ...0001-Fix-audio-choppiness-on-some-systems.patch |  36 +++++++
 .../0002-Fix-latency-related-buffer-sizing.patch   |  78 ++++++++++++++
 ...buffer-and-send-for-playback-without-bloc.patch | 118 +++++++++++++++++++++
 media-libs/pcaudiolib/pcaudiolib-1.2-r1.ebuild     |  51 +++++++++
 4 files changed, 283 insertions(+)

diff --git 
a/media-libs/pcaudiolib/files/0001-Fix-audio-choppiness-on-some-systems.patch 
b/media-libs/pcaudiolib/files/0001-Fix-audio-choppiness-on-some-systems.patch
new file mode 100644
index 000000000000..b8c147454df9
--- /dev/null
+++ 
b/media-libs/pcaudiolib/files/0001-Fix-audio-choppiness-on-some-systems.patch
@@ -0,0 +1,36 @@
+From 478bb69d51a945123a18dedf4bee7a3bede67f40 Mon Sep 17 00:00:00 2001
+From: Nicolas Pitre <n...@fluxnic.net>
+Date: Sat, 2 Apr 2022 22:04:30 -0400
+Subject: [PATCH] Fix audio choppiness on some systems
+
+Commit a41d46e816d2 ("Fix cancellation snappiness") made espeak unusable
+on the RaspberryPi due to extreme audio choppiness. This can sometimes
+be observed on some PC-type systems as well, albeit much less
+prominently.
+
+Relax the timing to the smallest value that makes it work again on the
+RaspberryPi.
+---
+ src/audio_priv.h | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/audio_priv.h b/src/audio_priv.h
+index 669a037..0c2ce3c 100644
+--- a/src/audio_priv.h
++++ b/src/audio_priv.h
+@@ -53,8 +53,10 @@ struct audio_object
+ };
+ 
+ /* We try to aim for 10ms cancelation latency, which will be perceived as
+- * "snappy" by users */
+-#define LATENCY 10
++ * "snappy" by users. However, some systems (e.g. RPi) do produce chopped
++ * audio when this value is smaller than 60.
++ */
++#define LATENCY 60
+ 
+ #if defined(_WIN32) || defined(_WIN64)
+ 
+-- 
+2.35.1
+

diff --git 
a/media-libs/pcaudiolib/files/0002-Fix-latency-related-buffer-sizing.patch 
b/media-libs/pcaudiolib/files/0002-Fix-latency-related-buffer-sizing.patch
new file mode 100644
index 000000000000..4af7da5c33a4
--- /dev/null
+++ b/media-libs/pcaudiolib/files/0002-Fix-latency-related-buffer-sizing.patch
@@ -0,0 +1,78 @@
+From 72da4a54a5afbbdadfa6d8131e0f4a9f08cf4394 Mon Sep 17 00:00:00 2001
+From: Nicolas Pitre <n...@fluxnic.net>
+Date: Wed, 6 Jul 2022 00:30:42 -0400
+Subject: [PATCH] Fix latency-related buffer sizing
+
+Turns out that eSpeak-NG (the main user of this lib) enforces a minimum
+buffer size of 60ms which is also the default size. This explains why
+smaller LATENCY values were inducing choppiness in the audio on some
+systems. Adjust the comment accordingly,.
+
+Also make sure computed buffer sizes don't land in the middle of a
+sample frame. Doing (samplerate * channels * LATENCY) / 1000 is wrong.
+
+Both ALSA and PulseAudio provide nice abstractions for buffer sizing
+so let's use them directly. In the ALSA case in particular, we want the
+period to be 60ms, not the whole buffer, so to interleave speech audio
+computation and audio playback.
+---
+ src/alsa.c       | 5 +++--
+ src/audio_priv.h | 5 +----
+ src/pulseaudio.c | 2 +-
+ 3 files changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/src/alsa.c b/src/alsa.c
+index c856788..a0da0f0 100644
+--- a/src/alsa.c
++++ b/src/alsa.c
+@@ -99,7 +99,8 @@ alsa_object_open(struct audio_object *object,
+ 
+       snd_pcm_hw_params_t *params = NULL;
+       snd_pcm_hw_params_malloc(&params);
+-      snd_pcm_uframes_t bufsize = (rate * channels * LATENCY) / 1000;
++      unsigned int period_time = LATENCY * 1000;
++      int dir = 0;
+ 
+       int err = 0;
+       if ((err = snd_pcm_open(&self->handle, self->device ? self->device : 
"default", SND_PCM_STREAM_PLAYBACK, 0)) < 0)
+@@ -114,7 +115,7 @@ alsa_object_open(struct audio_object *object,
+               goto error;
+       if ((err = snd_pcm_hw_params_set_channels(self->handle, params, 
channels)) < 0)
+               goto error;
+-      if ((err = snd_pcm_hw_params_set_buffer_size_near(self->handle, params, 
&bufsize)) < 0)
++      if ((err = snd_pcm_hw_params_set_period_time_near(self->handle, params, 
&period_time, &dir)) < 0)
+               goto error;
+       if ((err = snd_pcm_hw_params(self->handle, params)) < 0)
+               goto error;
+diff --git a/src/audio_priv.h b/src/audio_priv.h
+index 0c2ce3c..dbccb1c 100644
+--- a/src/audio_priv.h
++++ b/src/audio_priv.h
+@@ -52,10 +52,7 @@ struct audio_object
+                                int error);
+ };
+ 
+-/* We try to aim for 10ms cancelation latency, which will be perceived as
+- * "snappy" by users. However, some systems (e.g. RPi) do produce chopped
+- * audio when this value is smaller than 60.
+- */
++/* 60ms is the minimum and default buffer size used by eSpeak */
+ #define LATENCY 60
+ 
+ #if defined(_WIN32) || defined(_WIN64)
+diff --git a/src/pulseaudio.c b/src/pulseaudio.c
+index 2f80c62..da6c49f 100644
+--- a/src/pulseaudio.c
++++ b/src/pulseaudio.c
+@@ -80,7 +80,7 @@ pulseaudio_object_open(struct audio_object *object,
+       battr.maxlength = (uint32_t) -1;
+       battr.minreq = (uint32_t) -1;
+       battr.prebuf = (uint32_t) -1;
+-      battr.tlength = pa_bytes_per_second(&self->ss) * LATENCY / 1000;
++      battr.tlength = pa_usec_to_bytes(LATENCY * 1000, &self->ss);
+       self->s = pa_simple_new(NULL,
+                               self->application_name,
+                               PA_STREAM_PLAYBACK,
+-- 
+2.35.1
+

diff --git 
a/media-libs/pcaudiolib/files/0003-Copy-audio-buffer-and-send-for-playback-without-bloc.patch
 
b/media-libs/pcaudiolib/files/0003-Copy-audio-buffer-and-send-for-playback-without-bloc.patch
new file mode 100644
index 000000000000..5bc4eddc7edd
--- /dev/null
+++ 
b/media-libs/pcaudiolib/files/0003-Copy-audio-buffer-and-send-for-playback-without-bloc.patch
@@ -0,0 +1,118 @@
+From e0ff53614074feabc637598000f5799b480179c3 Mon Sep 17 00:00:00 2001
+From: zment <jani.karkkai...@gmail.com>
+Date: Tue, 16 Aug 2022 20:18:31 +0300
+Subject: [PATCH] Copy audio buffer and send for playback without blocking,
+ fixes Windows audio choppyness
+
+---
+ src/xaudio2.cpp | 60 +++++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 51 insertions(+), 9 deletions(-)
+
+diff --git a/src/xaudio2.cpp b/src/xaudio2.cpp
+index 72190b4..bb9d5be 100644
+--- a/src/xaudio2.cpp
++++ b/src/xaudio2.cpp
+@@ -35,6 +35,25 @@ struct xaudio2_object
+       LPWSTR devicename;
+ };
+ 
++class VoiceCallbacks : public IXAudio2VoiceCallback
++{
++public:
++      void OnBufferEnd(void* pBufferContext) {
++              if (pBufferContext != NULL)
++              {
++                      free((void*)pBufferContext);
++              }
++      }
++
++      // Stubs for all interface callbacks
++      void OnStreamEnd() { }
++      void OnVoiceProcessingPassEnd() { }
++      void OnVoiceProcessingPassStart(UINT32 SamplesRequired) { }
++      void OnBufferStart(void* pBufferContext) { }
++      void OnLoopEnd(void* pBufferContext) { }
++      void OnVoiceError(void* pBufferContext, HRESULT Error) { }
++} voiceCallbacks;
++
+ void
+ xaudio2_object_close(struct audio_object *object);
+ 
+@@ -59,7 +78,7 @@ xaudio2_object_open(struct audio_object *object,
+       if (FAILED(hr))
+               goto error;
+ 
+-      hr = self->audio->CreateSourceVoice(&self->source, self->format);
++      hr = self->audio->CreateSourceVoice(&self->source, self->format, 0, 
2.0f, &voiceCallbacks);
+       if (FAILED(hr))
+               goto error;
+ 
+@@ -110,6 +129,16 @@ xaudio2_object_drain(struct audio_object *object)
+ {
+       struct xaudio2_object *self = to_xaudio2_object(object);
+ 
++      while (true)
++      {
++              Sleep(10);
++
++              XAUDIO2_VOICE_STATE state = { 0 };
++              self->source->GetState(&state);
++              if (state.pCurrentBufferContext == NULL && state.BuffersQueued 
== 0)
++                      break;
++      }
++
+       return S_OK;
+ }
+ 
+@@ -128,27 +157,40 @@ xaudio2_object_write(struct audio_object *object,
+ {
+       struct xaudio2_object *self = to_xaudio2_object(object);
+ 
+-      XAUDIO2_BUFFER buffer = {0};
++      BYTE* buf_data = (BYTE *)malloc(bytes);
++      memcpy(buf_data, data, bytes);
++
++      XAUDIO2_BUFFER buffer = { 0 };
+       buffer.AudioBytes = bytes;
+-      buffer.pAudioData = (const BYTE *)data;
++      buffer.pAudioData = buf_data;
++      buffer.pContext = buf_data;
+ 
+       HRESULT hr = S_OK;
+       if (SUCCEEDED(hr))
+               hr = self->source->SubmitSourceBuffer(&buffer);
+ 
+-      if (SUCCEEDED(hr))
+-              hr = self->source->Start(0);
++      XAUDIO2_VOICE_STATE state = { 0 };
++      self->source->GetState(&state);
++      UINT32 buffersQueued = state.BuffersQueued;
+ 
+-      if (SUCCEEDED(hr)) while (true)
++      while (FAILED(hr))
+       {
+               Sleep(10);
+ 
+-              XAUDIO2_VOICE_STATE state = { 0 };
+               self->source->GetState(&state);
+-              if (state.pCurrentBufferContext == NULL && state.BuffersQueued 
== 0)
+-                      return hr;
++              if (state.BuffersQueued < buffersQueued)
++              {
++                      hr = self->source->SubmitSourceBuffer(&buffer);
++
++                      self->source->GetState(&state);
++                      buffersQueued = state.BuffersQueued;
++              }
+       }
+ 
++
++      if (SUCCEEDED(hr))
++              hr = self->source->Start(0);
++
+       return hr;
+ }
+ 
+-- 
+2.35.1
+

diff --git a/media-libs/pcaudiolib/pcaudiolib-1.2-r1.ebuild 
b/media-libs/pcaudiolib/pcaudiolib-1.2-r1.ebuild
new file mode 100644
index 000000000000..6525aa93e2a9
--- /dev/null
+++ b/media-libs/pcaudiolib/pcaudiolib-1.2-r1.ebuild
@@ -0,0 +1,51 @@
+# Copyright 1999-2022 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+inherit autotools
+
+DESCRIPTION="Portable C Audio Library"
+HOMEPAGE="https://github.com/espeak-ng/pcaudiolib";
+SRC_URI="https://github.com/espeak-ng/pcaudiolib/archive/${PV}.tar.gz -> 
${P}.tar.gz"
+
+LICENSE="GPL-3+ ZLIB"
+SLOT="0"
+KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~ia64 ~loong ~ppc ~ppc64 ~riscv 
~sparc ~x86"
+IUSE="+alsa oss pulseaudio"
+
+REQUIRED_USE="|| ( alsa oss pulseaudio )"
+
+RDEPEND="
+       alsa? ( >=media-libs/alsa-lib-1.0.18 )
+       pulseaudio? ( media-sound/pulseaudio )
+"
+DEPEND="${RDEPEND}"
+BDEPEND="virtual/pkgconfig"
+
+PATCHES=(
+       "${FILESDIR}/0001-Fix-audio-choppiness-on-some-systems.patch"
+       "${FILESDIR}/0002-Fix-latency-related-buffer-sizing.patch"
+       
"${FILESDIR}/0003-Copy-audio-buffer-and-send-for-playback-without-bloc.patch"
+       )
+
+src_prepare() {
+       default
+       eautoreconf
+}
+
+src_configure() {
+       local econf_args
+       econf_args=(
+               $(use_with oss)
+               $(use_with alsa)
+               $(use_with pulseaudio)
+               --disable-static
+       )
+       econf "${econf_args[@]}"
+}
+
+src_install() {
+       default
+       find "${ED}" -name '*.la' -delete || die
+}

Reply via email to