Github messages for voidlinux
 help / color / mirror / Atom feed
* [PR PATCH] libopenal: update to 1.21.1 and import fixes to sndio backend
@ 2022-02-13 20:22 mtboehlke
  2022-03-16 19:04 ` [PR PATCH] [Updated] " mtboehlke
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: mtboehlke @ 2022-02-13 20:22 UTC (permalink / raw)
  To: ml

[-- Attachment #1: Type: text/plain, Size: 1710 bytes --]

There is a new pull request by mtboehlke against master on the void-packages repository

https://github.com/mtboehlke/void-packages libopenal
https://github.com/void-linux/void-packages/pull/35594

libopenal: update to 1.21.1 and import fixes to sndio backend
Patches to fix the issue reported at https://github.com/kcat/openal-soft/issues/591

<!-- Uncomment relevant sections and delete options which are not applicable -->

#### Testing the changes
- I tested the changes in this PR: **briefly**

<!--
#### New package
- This new package conforms to the [quality requirements](https://github.com/void-linux/void-packages/blob/master/Manual.md#quality-requirements): **YES**|**NO**
-->

<!-- Note: If the build is likely to take more than 2 hours, please [skip CI](https://github.com/void-linux/void-packages/blob/master/CONTRIBUTING.md#continuous-integration)
and test at least one native build and, if supported, at least one cross build.
Ignore this section if this PR is not skipping CI.
-->
<!-- 
#### Local build testing
- I built this PR locally for my native architecture, (ARCH-LIBC)
- I built this PR locally for these architectures (if supported. mark crossbuilds):
  - aarch64-musl
  - armv7l
  - armv6l-musl
-->
I encountered the problem described in the linked issue when playing around with wildmidi.  I was hoping to have wildmidi use sndio by compiling without direct alsa support, and then rely on libopenal to use sndio.  This worked fine with the default openal configuration, but playback stopped immediately, with the error message: `[ALSOFT] (EE) Error stopping device`

A patch file from https://github.com/void-linux/void-packages/pull/35594.patch is attached

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: github-pr-libopenal-35594.patch --]
[-- Type: text/x-diff, Size: 20003 bytes --]

From 6eeaba6339041116400f7bdaa6352926df7bfcf0 Mon Sep 17 00:00:00 2001
From: Mat Boehlke <mtboehlke@gmail.com>
Date: Sun, 13 Feb 2022 13:59:19 -0600
Subject: [PATCH] libopenal: update to 1.21.1 and import fixes to sndio backend

Patches to fix the issue reported at https://github.com/kcat/openal-soft/issues/591
---
 .../sndio-simplify-channel-handling.patch     | 242 ++++++++++++++++++
 .../use-nonblock-mode-sndio-capture.patch     | 239 +++++++++++++++++
 srcpkgs/libopenal/template                    |   8 +-
 3 files changed, 485 insertions(+), 4 deletions(-)
 create mode 100644 srcpkgs/libopenal/patches/sndio-simplify-channel-handling.patch
 create mode 100644 srcpkgs/libopenal/patches/use-nonblock-mode-sndio-capture.patch

diff --git a/srcpkgs/libopenal/patches/sndio-simplify-channel-handling.patch b/srcpkgs/libopenal/patches/sndio-simplify-channel-handling.patch
new file mode 100644
index 000000000000..909943e4e22f
--- /dev/null
+++ b/srcpkgs/libopenal/patches/sndio-simplify-channel-handling.patch
@@ -0,0 +1,242 @@
+From 620836f173ae6fc4505d0634984e0f2c46166367 Mon Sep 17 00:00:00 2001
+From: Chris Robinson <chris.kcat@gmail.com>
+Date: Thu, 29 Jul 2021 21:07:20 -0700
+Subject: [PATCH] Simplify channel handling in the sndio backend
+
+---
+ alc/backends/sndio.cpp | 152 +++++++++++++++++------------------------
+ 1 file changed, 63 insertions(+), 89 deletions(-)
+
+diff --git a/alc/backends/sndio.cpp b/alc/backends/sndio.cpp
+index 2d8b424c9..c41c6c8bc 100644
+--- a/alc/backends/sndio.cpp
++++ b/alc/backends/sndio.cpp
+@@ -44,6 +44,11 @@ namespace {
+ 
+ static const char sndio_device[] = "SndIO Default";
+ 
++struct SioPar : public sio_par {
++    SioPar() { sio_initpar(this); }
++
++    void clear() { sio_initpar(this); }
++};
+ 
+ struct SndioPlayback final : public BackendBase {
+     SndioPlayback(DeviceBase *device) noexcept : BackendBase{device} { }
+@@ -57,6 +62,7 @@ struct SndioPlayback final : public BackendBase {
+     void stop() override;
+ 
+     sio_hdl *mSndHandle{nullptr};
++    uint mFrameStep{};
+ 
+     al::vector<al::byte> mBuffer;
+ 
+@@ -75,16 +81,8 @@ SndioPlayback::~SndioPlayback()
+ 
+ int SndioPlayback::mixerProc()
+ {
+-    sio_par par;
+-    sio_initpar(&par);
+-    if(!sio_getpar(mSndHandle, &par))
+-    {
+-        mDevice->handleDisconnect("Failed to get device parameters");
+-        return 1;
+-    }
+-
+-    const size_t frameStep{par.pchan};
+-    const size_t frameSize{frameStep * par.bps};
++    const size_t frameStep{mFrameStep};
++    const size_t frameSize{frameStep * mDevice->bytesFromFmt()};
+ 
+     SetRTPriority();
+     althrd_setname(MIXER_THREAD_NAME);
+@@ -92,22 +90,20 @@ int SndioPlayback::mixerProc()
+     while(!mKillNow.load(std::memory_order_acquire)
+         && mDevice->Connected.load(std::memory_order_acquire))
+     {
+-        al::byte *WritePtr{mBuffer.data()};
+-        size_t len{mBuffer.size()};
++        al::span<al::byte> buffer{mBuffer};
+ 
+-        mDevice->renderSamples(WritePtr, static_cast<uint>(len/frameSize), frameStep);
+-        while(len > 0 && !mKillNow.load(std::memory_order_acquire))
++        mDevice->renderSamples(buffer.data(), static_cast<uint>(buffer.size() / frameSize),
++            frameStep);
++        while(!buffer.empty() && !mKillNow.load(std::memory_order_acquire))
+         {
+-            size_t wrote{sio_write(mSndHandle, WritePtr, len)};
++            size_t wrote{sio_write(mSndHandle, buffer.data(), buffer.size())};
+             if(wrote == 0)
+             {
+                 ERR("sio_write failed\n");
+                 mDevice->handleDisconnect("Failed to write playback samples");
+                 break;
+             }
+-
+-            len -= wrote;
+-            WritePtr += wrote;
++            buffer = buffer.subspan(wrote);
+         }
+     }
+ 
+@@ -136,25 +132,11 @@ void SndioPlayback::open(const char *name)
+ 
+ bool SndioPlayback::reset()
+ {
+-    sio_par par;
+-    sio_initpar(&par);
++    SioPar par;
+ 
+-    par.rate = mDevice->Frequency;
+-    switch(mDevice->FmtChans)
+-    {
+-    case DevFmtMono   : par.pchan = 1; break;
+-    case DevFmtQuad   : par.pchan = 4; break;
+-    case DevFmtX51Rear: // fall-through - "Similar to 5.1, except using rear channels instead of sides"
+-    case DevFmtX51    : par.pchan = 6; break;
+-    case DevFmtX61    : par.pchan = 7; break;
+-    case DevFmtX71    : par.pchan = 8; break;
+-
+-    // fall back to stereo for Ambi3D
+-    case DevFmtAmbi3D : // fall-through
+-    case DevFmtStereo : par.pchan = 2; break;
+-    }
+-
+-    switch(mDevice->FmtType)
++    auto tryfmt = mDevice->FmtType;
++retry_params:
++    switch(tryfmt)
+     {
+     case DevFmtByte:
+         par.bits = 8;
+@@ -164,7 +146,6 @@ bool SndioPlayback::reset()
+         par.bits = 8;
+         par.sig = 0;
+         break;
+-    case DevFmtFloat:
+     case DevFmtShort:
+         par.bits = 16;
+         par.sig = 1;
+@@ -173,6 +154,7 @@ bool SndioPlayback::reset()
+         par.bits = 16;
+         par.sig = 0;
+         break;
++    case DevFmtFloat:
+     case DevFmtInt:
+         par.bits = 32;
+         par.sig = 1;
+@@ -182,70 +164,62 @@ bool SndioPlayback::reset()
+         par.sig = 0;
+         break;
+     }
++    par.bps = SIO_BPS(par.bits);
+     par.le = SIO_LE_NATIVE;
+ 
++    par.rate = mDevice->Frequency;
++    par.pchan = mDevice->channelsFromFmt();
++
+     par.round = mDevice->UpdateSize;
+     par.appbufsz = mDevice->BufferSize - mDevice->UpdateSize;
+     if(!par.appbufsz) par.appbufsz = mDevice->UpdateSize;
+ 
+-    if(!sio_setpar(mSndHandle, &par) || !sio_getpar(mSndHandle, &par))
+-    {
+-        ERR("Failed to set device parameters\n");
+-        return false;
+-    }
+-
+-    if(par.bits != par.bps*8)
+-    {
+-        ERR("Padded samples not supported (%u of %u bits)\n", par.bits, par.bps*8);
+-        return false;
+-    }
+-    if(par.le != SIO_LE_NATIVE)
+-    {
+-        ERR("Non-native-endian samples not supported (got %s-endian)\n",
+-            par.le ? "little" : "big");
+-        return false;
+-    }
+-
+-    mDevice->Frequency = par.rate;
+-
+-    if(par.pchan < 2)
+-    {
+-        if(mDevice->FmtChans != DevFmtMono)
+-        {
+-            WARN("Got %u channel for %s\n", par.pchan, DevFmtChannelsString(mDevice->FmtChans));
+-            mDevice->FmtChans = DevFmtMono;
+-        }
++    try {
++        if(!sio_setpar(mSndHandle, &par))
++            throw al::backend_exception{al::backend_error::DeviceError,
++                "Failed to set device parameters"};
++
++        par.clear();
++        if(!sio_getpar(mSndHandle, &par))
++            throw al::backend_exception{al::backend_error::DeviceError,
++                "Failed to get device parameters"};
++
++        if(par.bps > 1 && par.le != SIO_LE_NATIVE)
++            throw al::backend_exception{al::backend_error::DeviceError,
++                "%s-endian samples not supported", par.le ? "Little" : "Big"};
++        if(par.bits < par.bps*8 && !par.msb)
++            throw al::backend_exception{al::backend_error::DeviceError,
++                "MSB-padded samples not supported (%u of %u bits)", par.bits, par.bps*8};
++        if(par.pchan < 1)
++            throw al::backend_exception{al::backend_error::DeviceError,
++                "No playback channels on device"};
+     }
+-    else if((par.pchan == 2 && mDevice->FmtChans != DevFmtStereo)
+-        || par.pchan == 3
+-        || (par.pchan == 4 && mDevice->FmtChans != DevFmtQuad)
+-        || par.pchan == 5
+-        || (par.pchan == 6 && mDevice->FmtChans != DevFmtX51 && mDevice->FmtChans != DevFmtX51Rear)
+-        || (par.pchan == 7 && mDevice->FmtChans != DevFmtX61)
+-        || (par.pchan == 8 && mDevice->FmtChans != DevFmtX71)
+-        || par.pchan > 8)
+-    {
+-        WARN("Got %u channels for %s\n", par.pchan, DevFmtChannelsString(mDevice->FmtChans));
+-        mDevice->FmtChans = DevFmtStereo;
++    catch(al::backend_exception &e) {
++        if(tryfmt == DevFmtShort)
++            throw;
++        tryfmt = DevFmtShort;
++        goto retry_params;
+     }
+ 
+-    if(par.bits == 8 && par.sig == 1)
+-        mDevice->FmtType = DevFmtByte;
+-    else if(par.bits == 8 && par.sig == 0)
+-        mDevice->FmtType = DevFmtUByte;
+-    else if(par.bits == 16 && par.sig == 1)
+-        mDevice->FmtType = DevFmtShort;
+-    else if(par.bits == 16 && par.sig == 0)
+-        mDevice->FmtType = DevFmtUShort;
+-    else if(par.bits == 32 && par.sig == 1)
+-        mDevice->FmtType = DevFmtInt;
+-    else if(par.bits == 32 && par.sig == 0)
+-        mDevice->FmtType = DevFmtUInt;
++    if(par.bps == 1)
++        mDevice->FmtType = (par.sig==1) ? DevFmtByte : DevFmtUByte;
++    else if(par.bps == 2)
++        mDevice->FmtType = (par.sig==1) ? DevFmtShort : DevFmtUShort;
++    else if(par.bps == 4)
++        mDevice->FmtType = (par.sig==1) ? DevFmtInt : DevFmtUInt;
+     else
++        throw al::backend_exception{al::backend_error::DeviceError,
++            "Unhandled sample format: %s %u-bit", (par.sig?"signed":"unsigned"), par.bps*8};
++
++    mFrameStep = par.pchan;
++    if(par.pchan != mDevice->channelsFromFmt())
+     {
+-        ERR("Unhandled sample format: %s %u-bit\n", (par.sig?"signed":"unsigned"), par.bits);
+-        return false;
++        WARN("Got %u channel%s for %s\n", par.pchan, (par.pchan==1)?"":"s",
++            DevFmtChannelsString(mDevice->FmtChans));
++        if(par.pchan < 2) mDevice->FmtChans = DevFmtMono;
++        else mDevice->FmtChans = DevFmtStereo;
+     }
++    mDevice->Frequency = par.rate;
+ 
+     setDefaultChannelOrder();
+ 
diff --git a/srcpkgs/libopenal/patches/use-nonblock-mode-sndio-capture.patch b/srcpkgs/libopenal/patches/use-nonblock-mode-sndio-capture.patch
new file mode 100644
index 000000000000..34520ada3ad1
--- /dev/null
+++ b/srcpkgs/libopenal/patches/use-nonblock-mode-sndio-capture.patch
@@ -0,0 +1,239 @@
+From 1fd4c865fc084f134363db5155361d5483679235 Mon Sep 17 00:00:00 2001
+From: Chris Robinson <chris.kcat@gmail.com>
+Date: Fri, 30 Jul 2021 04:15:00 -0700
+Subject: [PATCH] Use non-block mode for sndio capture
+
+---
+ alc/backends/sndio.cpp | 123 +++++++++++++++++++++++++----------------
+ 1 file changed, 76 insertions(+), 47 deletions(-)
+
+diff --git a/alc/backends/sndio.cpp b/alc/backends/sndio.cpp
+index c41c6c8bc..6852e01a2 100644
+--- a/alc/backends/sndio.cpp
++++ b/alc/backends/sndio.cpp
+@@ -22,6 +22,7 @@
+ 
+ #include "sndio.h"
+ 
++#include <poll.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -166,6 +167,7 @@ bool SndioPlayback::reset()
+     }
+     par.bps = SIO_BPS(par.bits);
+     par.le = SIO_LE_NATIVE;
++    par.msb = 1;
+ 
+     par.rate = mDevice->Frequency;
+     par.pchan = mDevice->channelsFromFmt();
+@@ -197,6 +199,7 @@ bool SndioPlayback::reset()
+     catch(al::backend_exception &e) {
+         if(tryfmt == DevFmtShort)
+             throw;
++        par.clear();
+         tryfmt = DevFmtShort;
+         goto retry_params;
+     }
+@@ -266,6 +269,11 @@ void SndioPlayback::stop()
+ }
+ 
+ 
++/* TODO: This could be improved by avoiding the ring buffer and record thread,
++ * counting the available samples with the sio_onmove callback and reading
++ * directly from the device. However, this depends on reasonable support for
++ * capture buffer sizes apps may request.
++ */
+ struct SndioCapture final : public BackendBase {
+     SndioCapture(DeviceBase *device) noexcept : BackendBase{device} { }
+     ~SndioCapture() override;
+@@ -280,6 +288,7 @@ struct SndioCapture final : public BackendBase {
+ 
+     sio_hdl *mSndHandle{nullptr};
+ 
++    al::vector<struct pollfd> mFds;
+     RingBufferPtr mRing;
+ 
+     std::atomic<bool> mKillNow{true};
+@@ -305,37 +314,53 @@ int SndioCapture::recordProc()
+     while(!mKillNow.load(std::memory_order_acquire)
+         && mDevice->Connected.load(std::memory_order_acquire))
+     {
+-        auto data = mRing->getWriteVector();
+-        size_t todo{data.first.len + data.second.len};
+-        if(todo == 0)
++        /* Wait until there's some samples to read. */
++        const int nfds{sio_pollfd(mSndHandle, mFds.data(), POLLIN)};
++        if(nfds <= 0)
+         {
+-            static char junk[4096];
+-            sio_read(mSndHandle, junk,
+-                minz(sizeof(junk)/frameSize, mDevice->UpdateSize)*frameSize);
++            mDevice->handleDisconnect("Failed to get polling fds: %d", nfds);
++            break;
++        }
++        int pollres{::poll(mFds.data(), static_cast<uint>(nfds), 2000)};
++        if(pollres < 0)
++        {
++            if(errno == EINTR) continue;
++            mDevice->handleDisconnect("Poll error: %s", strerror(errno));
++            break;
++        }
++        if(pollres == 0)
+             continue;
++
++        const int revents{sio_revents(mSndHandle, mFds.data())};
++        if((revents&POLLHUP))
++        {
++            mDevice->handleDisconnect("Got POLLHUP from poll events");
++            break;
+         }
++        if(!(revents&POLLIN))
++            continue;
+ 
+-        size_t total{0u};
+-        data.first.len  *= frameSize;
+-        data.second.len *= frameSize;
+-        todo = minz(todo, mDevice->UpdateSize) * frameSize;
+-        while(total < todo)
++        auto data = mRing->getWriteVector();
++        al::span<al::byte> buffer{data.first.buf, data.first.len*frameSize};
++        while(!buffer.empty())
+         {
+-            if(!data.first.len)
+-                data.first = data.second;
++            size_t got{sio_read(mSndHandle, buffer.data(), buffer.size())};
++            if(got == 0) break;
+ 
+-            size_t got{sio_read(mSndHandle, data.first.buf, minz(todo-total, data.first.len))};
+-            if(!got)
++            mRing->writeAdvance(got / frameSize);
++            buffer = buffer.subspan(got);
++            if(buffer.empty())
+             {
+-                mDevice->handleDisconnect("Failed to read capture samples");
+-                break;
++                data = mRing->getWriteVector();
++                buffer = {data.first.buf, data.first.len*frameSize};
+             }
+-
+-            data.first.buf += got;
+-            data.first.len -= got;
+-            total += got;
+         }
+-        mRing->writeAdvance(total / frameSize);
++        if(buffer.empty())
++        {
++            /* Got samples to read, but no place to store it. Drop it. */
++            static char junk[4096];
++            sio_read(mSndHandle, junk, sizeof(junk) - (sizeof(junk)%frameSize));
++        }
+     }
+ 
+     return 0;
+@@ -350,76 +375,80 @@ void SndioCapture::open(const char *name)
+         throw al::backend_exception{al::backend_error::NoDevice, "Device name \"%s\" not found",
+             name};
+ 
+-    mSndHandle = sio_open(nullptr, SIO_REC, 0);
++    mSndHandle = sio_open(nullptr, SIO_REC, true);
+     if(mSndHandle == nullptr)
+         throw al::backend_exception{al::backend_error::NoDevice, "Could not open backend device"};
+ 
+-    sio_par par;
+-    sio_initpar(&par);
+-
++    SioPar par;
+     switch(mDevice->FmtType)
+     {
+     case DevFmtByte:
+-        par.bps = 1;
++        par.bits = 8;
+         par.sig = 1;
+         break;
+     case DevFmtUByte:
+-        par.bps = 1;
++        par.bits = 8;
+         par.sig = 0;
+         break;
+     case DevFmtShort:
+-        par.bps = 2;
++        par.bits = 16;
+         par.sig = 1;
+         break;
+     case DevFmtUShort:
+-        par.bps = 2;
++        par.bits = 16;
+         par.sig = 0;
+         break;
+     case DevFmtInt:
+-        par.bps = 4;
++        par.bits = 32;
+         par.sig = 1;
+         break;
+     case DevFmtUInt:
+-        par.bps = 4;
++        par.bits = 32;
+         par.sig = 0;
+         break;
+     case DevFmtFloat:
+         throw al::backend_exception{al::backend_error::DeviceError,
+             "%s capture samples not supported", DevFmtTypeString(mDevice->FmtType)};
+     }
+-    par.bits = par.bps * 8;
++    par.bps = SIO_BPS(par.bits);
+     par.le = SIO_LE_NATIVE;
+-    par.msb = SIO_LE_NATIVE ? 0 : 1;
++    par.msb = 1;
+     par.rchan = mDevice->channelsFromFmt();
+     par.rate = mDevice->Frequency;
+ 
+     par.appbufsz = maxu(mDevice->BufferSize, mDevice->Frequency/10);
+-    par.round = minu(par.appbufsz, mDevice->Frequency/40);
+-
+-    mDevice->UpdateSize = par.round;
+-    mDevice->BufferSize = par.appbufsz;
++    par.round = minu(par.appbufsz/2, mDevice->Frequency/40);
+ 
+     if(!sio_setpar(mSndHandle, &par) || !sio_getpar(mSndHandle, &par))
+         throw al::backend_exception{al::backend_error::DeviceError,
+             "Failed to set device praameters"};
+ 
+-    if(par.bits != par.bps*8)
++    if(par.bps > 1 && par.le != SIO_LE_NATIVE)
++        throw al::backend_exception{al::backend_error::DeviceError,
++            "%s-endian samples not supported", par.le ? "Little" : "Big"};
++    if(par.bits < par.bps*8 && !par.msb)
+         throw al::backend_exception{al::backend_error::DeviceError,
+             "Padded samples not supported (got %u of %u bits)", par.bits, par.bps*8};
+ 
+-    if(!((mDevice->FmtType == DevFmtByte && par.bits == 8 && par.sig != 0)
+-        || (mDevice->FmtType == DevFmtUByte && par.bits == 8 && par.sig == 0)
+-        || (mDevice->FmtType == DevFmtShort && par.bits == 16 && par.sig != 0)
+-        || (mDevice->FmtType == DevFmtUShort && par.bits == 16 && par.sig == 0)
+-        || (mDevice->FmtType == DevFmtInt && par.bits == 32 && par.sig != 0)
+-        || (mDevice->FmtType == DevFmtUInt && par.bits == 32 && par.sig == 0))
+-        || mDevice->channelsFromFmt() != par.rchan || mDevice->Frequency != par.rate)
++    auto match_fmt = [](DevFmtType fmttype, const sio_par &par) -> bool
++    {
++        return (fmttype == DevFmtByte && par.bps == 1 && par.sig != 0)
++            || (fmttype == DevFmtUByte && par.bps == 1 && par.sig == 0)
++            || (fmttype == DevFmtShort && par.bps == 2 && par.sig != 0)
++            || (fmttype == DevFmtUShort && par.bps == 2 && par.sig == 0)
++            || (fmttype == DevFmtInt && par.bps == 4 && par.sig != 0)
++            || (fmttype == DevFmtUInt && par.bps == 4 && par.sig == 0);
++    };
++    if(!match_fmt(mDevice->FmtType, par) || mDevice->channelsFromFmt() != par.rchan
++        || mDevice->Frequency != par.rate)
+         throw al::backend_exception{al::backend_error::DeviceError,
+             "Failed to set format %s %s %uhz, got %c%u %u-channel %uhz instead",
+             DevFmtTypeString(mDevice->FmtType), DevFmtChannelsString(mDevice->FmtChans),
+-            mDevice->Frequency, par.sig?'s':'u', par.bits, par.rchan, par.rate};
++            mDevice->Frequency, par.sig?'s':'u', par.bps*8, par.rchan, par.rate};
+ 
+     mRing = RingBuffer::Create(mDevice->BufferSize, par.bps*par.rchan, false);
++    mDevice->BufferSize = static_cast<uint>(mRing->writeSpace());
++    mDevice->UpdateSize = par.round;
+ 
+     setDefaultChannelOrder();
+ 
diff --git a/srcpkgs/libopenal/template b/srcpkgs/libopenal/template
index c89016a3584b..441e138d3c65 100644
--- a/srcpkgs/libopenal/template
+++ b/srcpkgs/libopenal/template
@@ -1,6 +1,6 @@
 # Template file for 'libopenal'
 pkgname=libopenal
-version=1.21.0
+version=1.21.1
 revision=1
 wrksrc="openal-soft-${version}"
 build_style=cmake
@@ -11,9 +11,9 @@ makedepends="zlib-devel alsa-lib-devel pulseaudio-devel SDL2-devel ffmpeg-devel
 short_desc="Cross-platform 3D audio library"
 maintainer="Orphaned <orphan@voidlinux.org>"
 license="LGPL-2.1-or-later"
-homepage="http://openal-soft.org/"
-distfiles="http://openal-soft.org/openal-releases/openal-soft-${version}.tar.bz2"
-checksum=2916b4fc24e23b0271ce0b3468832ad8b6d8441b1830215b28cc4fee6cc89297
+homepage="https://openal-soft.org/"
+distfiles="https://openal-soft.org/openal-releases/openal-soft-${version}.tar.bz2"
+checksum=c8ad767e9a3230df66756a21cc8ebf218a9d47288f2514014832204e666af5d8
 
 build_options="sndio"
 build_options_default="sndio"

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PR PATCH] [Updated] libopenal: update to 1.21.1 and import fixes to sndio backend
  2022-02-13 20:22 [PR PATCH] libopenal: update to 1.21.1 and import fixes to sndio backend mtboehlke
@ 2022-03-16 19:04 ` mtboehlke
  2022-04-19 16:15 ` mtboehlke
  2022-04-29 15:45 ` [PR PATCH] [Closed]: " mtboehlke
  2 siblings, 0 replies; 4+ messages in thread
From: mtboehlke @ 2022-03-16 19:04 UTC (permalink / raw)
  To: ml

[-- Attachment #1: Type: text/plain, Size: 1776 bytes --]

There is an updated pull request by mtboehlke against master on the void-packages repository

https://github.com/mtboehlke/void-packages libopenal
https://github.com/void-linux/void-packages/pull/35594

libopenal: update to 1.21.1 and import fixes to sndio backend
Patches to fix the issue reported at https://github.com/kcat/openal-soft/issues/591

<!-- Uncomment relevant sections and delete options which are not applicable -->

#### Testing the changes
- I tested the changes in this PR: **briefly**

<!--
#### New package
- This new package conforms to the [quality requirements](https://github.com/void-linux/void-packages/blob/master/Manual.md#quality-requirements): **YES**|**NO**
-->

<!-- Note: If the build is likely to take more than 2 hours, please [skip CI](https://github.com/void-linux/void-packages/blob/master/CONTRIBUTING.md#continuous-integration)
and test at least one native build and, if supported, at least one cross build.
Ignore this section if this PR is not skipping CI.
-->
<!-- 
#### Local build testing
- I built this PR locally for my native architecture, (ARCH-LIBC)
- I built this PR locally for these architectures (if supported. mark crossbuilds):
  - aarch64-musl
  - armv7l
  - armv6l-musl
-->
I encountered the problem described in the linked issue when playing around with wildmidi.  I was hoping to have wildmidi use sndio by compiling without direct alsa support, and then rely on libopenal to use sndio.  When libopenal was configured for sndio, playback stopped immediately with the error message: `[ALSOFT] (EE) Error stopping device`.  Playback worked as expected with sndio after including these upstream patches.

A patch file from https://github.com/void-linux/void-packages/pull/35594.patch is attached

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: github-pr-libopenal-35594.patch --]
[-- Type: text/x-diff, Size: 20003 bytes --]

From bdca0ef3a4ba449e0ac12f335f27bd22f82209fd Mon Sep 17 00:00:00 2001
From: Mat Boehlke <mtboehlke@gmail.com>
Date: Sun, 13 Feb 2022 13:59:19 -0600
Subject: [PATCH] libopenal: update to 1.21.1 and import fixes to sndio backend

Patches to fix the issue reported at https://github.com/kcat/openal-soft/issues/591
---
 .../sndio-simplify-channel-handling.patch     | 242 ++++++++++++++++++
 .../use-nonblock-mode-sndio-capture.patch     | 239 +++++++++++++++++
 srcpkgs/libopenal/template                    |   8 +-
 3 files changed, 485 insertions(+), 4 deletions(-)
 create mode 100644 srcpkgs/libopenal/patches/sndio-simplify-channel-handling.patch
 create mode 100644 srcpkgs/libopenal/patches/use-nonblock-mode-sndio-capture.patch

diff --git a/srcpkgs/libopenal/patches/sndio-simplify-channel-handling.patch b/srcpkgs/libopenal/patches/sndio-simplify-channel-handling.patch
new file mode 100644
index 000000000000..909943e4e22f
--- /dev/null
+++ b/srcpkgs/libopenal/patches/sndio-simplify-channel-handling.patch
@@ -0,0 +1,242 @@
+From 620836f173ae6fc4505d0634984e0f2c46166367 Mon Sep 17 00:00:00 2001
+From: Chris Robinson <chris.kcat@gmail.com>
+Date: Thu, 29 Jul 2021 21:07:20 -0700
+Subject: [PATCH] Simplify channel handling in the sndio backend
+
+---
+ alc/backends/sndio.cpp | 152 +++++++++++++++++------------------------
+ 1 file changed, 63 insertions(+), 89 deletions(-)
+
+diff --git a/alc/backends/sndio.cpp b/alc/backends/sndio.cpp
+index 2d8b424c9..c41c6c8bc 100644
+--- a/alc/backends/sndio.cpp
++++ b/alc/backends/sndio.cpp
+@@ -44,6 +44,11 @@ namespace {
+ 
+ static const char sndio_device[] = "SndIO Default";
+ 
++struct SioPar : public sio_par {
++    SioPar() { sio_initpar(this); }
++
++    void clear() { sio_initpar(this); }
++};
+ 
+ struct SndioPlayback final : public BackendBase {
+     SndioPlayback(DeviceBase *device) noexcept : BackendBase{device} { }
+@@ -57,6 +62,7 @@ struct SndioPlayback final : public BackendBase {
+     void stop() override;
+ 
+     sio_hdl *mSndHandle{nullptr};
++    uint mFrameStep{};
+ 
+     al::vector<al::byte> mBuffer;
+ 
+@@ -75,16 +81,8 @@ SndioPlayback::~SndioPlayback()
+ 
+ int SndioPlayback::mixerProc()
+ {
+-    sio_par par;
+-    sio_initpar(&par);
+-    if(!sio_getpar(mSndHandle, &par))
+-    {
+-        mDevice->handleDisconnect("Failed to get device parameters");
+-        return 1;
+-    }
+-
+-    const size_t frameStep{par.pchan};
+-    const size_t frameSize{frameStep * par.bps};
++    const size_t frameStep{mFrameStep};
++    const size_t frameSize{frameStep * mDevice->bytesFromFmt()};
+ 
+     SetRTPriority();
+     althrd_setname(MIXER_THREAD_NAME);
+@@ -92,22 +90,20 @@ int SndioPlayback::mixerProc()
+     while(!mKillNow.load(std::memory_order_acquire)
+         && mDevice->Connected.load(std::memory_order_acquire))
+     {
+-        al::byte *WritePtr{mBuffer.data()};
+-        size_t len{mBuffer.size()};
++        al::span<al::byte> buffer{mBuffer};
+ 
+-        mDevice->renderSamples(WritePtr, static_cast<uint>(len/frameSize), frameStep);
+-        while(len > 0 && !mKillNow.load(std::memory_order_acquire))
++        mDevice->renderSamples(buffer.data(), static_cast<uint>(buffer.size() / frameSize),
++            frameStep);
++        while(!buffer.empty() && !mKillNow.load(std::memory_order_acquire))
+         {
+-            size_t wrote{sio_write(mSndHandle, WritePtr, len)};
++            size_t wrote{sio_write(mSndHandle, buffer.data(), buffer.size())};
+             if(wrote == 0)
+             {
+                 ERR("sio_write failed\n");
+                 mDevice->handleDisconnect("Failed to write playback samples");
+                 break;
+             }
+-
+-            len -= wrote;
+-            WritePtr += wrote;
++            buffer = buffer.subspan(wrote);
+         }
+     }
+ 
+@@ -136,25 +132,11 @@ void SndioPlayback::open(const char *name)
+ 
+ bool SndioPlayback::reset()
+ {
+-    sio_par par;
+-    sio_initpar(&par);
++    SioPar par;
+ 
+-    par.rate = mDevice->Frequency;
+-    switch(mDevice->FmtChans)
+-    {
+-    case DevFmtMono   : par.pchan = 1; break;
+-    case DevFmtQuad   : par.pchan = 4; break;
+-    case DevFmtX51Rear: // fall-through - "Similar to 5.1, except using rear channels instead of sides"
+-    case DevFmtX51    : par.pchan = 6; break;
+-    case DevFmtX61    : par.pchan = 7; break;
+-    case DevFmtX71    : par.pchan = 8; break;
+-
+-    // fall back to stereo for Ambi3D
+-    case DevFmtAmbi3D : // fall-through
+-    case DevFmtStereo : par.pchan = 2; break;
+-    }
+-
+-    switch(mDevice->FmtType)
++    auto tryfmt = mDevice->FmtType;
++retry_params:
++    switch(tryfmt)
+     {
+     case DevFmtByte:
+         par.bits = 8;
+@@ -164,7 +146,6 @@ bool SndioPlayback::reset()
+         par.bits = 8;
+         par.sig = 0;
+         break;
+-    case DevFmtFloat:
+     case DevFmtShort:
+         par.bits = 16;
+         par.sig = 1;
+@@ -173,6 +154,7 @@ bool SndioPlayback::reset()
+         par.bits = 16;
+         par.sig = 0;
+         break;
++    case DevFmtFloat:
+     case DevFmtInt:
+         par.bits = 32;
+         par.sig = 1;
+@@ -182,70 +164,62 @@ bool SndioPlayback::reset()
+         par.sig = 0;
+         break;
+     }
++    par.bps = SIO_BPS(par.bits);
+     par.le = SIO_LE_NATIVE;
+ 
++    par.rate = mDevice->Frequency;
++    par.pchan = mDevice->channelsFromFmt();
++
+     par.round = mDevice->UpdateSize;
+     par.appbufsz = mDevice->BufferSize - mDevice->UpdateSize;
+     if(!par.appbufsz) par.appbufsz = mDevice->UpdateSize;
+ 
+-    if(!sio_setpar(mSndHandle, &par) || !sio_getpar(mSndHandle, &par))
+-    {
+-        ERR("Failed to set device parameters\n");
+-        return false;
+-    }
+-
+-    if(par.bits != par.bps*8)
+-    {
+-        ERR("Padded samples not supported (%u of %u bits)\n", par.bits, par.bps*8);
+-        return false;
+-    }
+-    if(par.le != SIO_LE_NATIVE)
+-    {
+-        ERR("Non-native-endian samples not supported (got %s-endian)\n",
+-            par.le ? "little" : "big");
+-        return false;
+-    }
+-
+-    mDevice->Frequency = par.rate;
+-
+-    if(par.pchan < 2)
+-    {
+-        if(mDevice->FmtChans != DevFmtMono)
+-        {
+-            WARN("Got %u channel for %s\n", par.pchan, DevFmtChannelsString(mDevice->FmtChans));
+-            mDevice->FmtChans = DevFmtMono;
+-        }
++    try {
++        if(!sio_setpar(mSndHandle, &par))
++            throw al::backend_exception{al::backend_error::DeviceError,
++                "Failed to set device parameters"};
++
++        par.clear();
++        if(!sio_getpar(mSndHandle, &par))
++            throw al::backend_exception{al::backend_error::DeviceError,
++                "Failed to get device parameters"};
++
++        if(par.bps > 1 && par.le != SIO_LE_NATIVE)
++            throw al::backend_exception{al::backend_error::DeviceError,
++                "%s-endian samples not supported", par.le ? "Little" : "Big"};
++        if(par.bits < par.bps*8 && !par.msb)
++            throw al::backend_exception{al::backend_error::DeviceError,
++                "MSB-padded samples not supported (%u of %u bits)", par.bits, par.bps*8};
++        if(par.pchan < 1)
++            throw al::backend_exception{al::backend_error::DeviceError,
++                "No playback channels on device"};
+     }
+-    else if((par.pchan == 2 && mDevice->FmtChans != DevFmtStereo)
+-        || par.pchan == 3
+-        || (par.pchan == 4 && mDevice->FmtChans != DevFmtQuad)
+-        || par.pchan == 5
+-        || (par.pchan == 6 && mDevice->FmtChans != DevFmtX51 && mDevice->FmtChans != DevFmtX51Rear)
+-        || (par.pchan == 7 && mDevice->FmtChans != DevFmtX61)
+-        || (par.pchan == 8 && mDevice->FmtChans != DevFmtX71)
+-        || par.pchan > 8)
+-    {
+-        WARN("Got %u channels for %s\n", par.pchan, DevFmtChannelsString(mDevice->FmtChans));
+-        mDevice->FmtChans = DevFmtStereo;
++    catch(al::backend_exception &e) {
++        if(tryfmt == DevFmtShort)
++            throw;
++        tryfmt = DevFmtShort;
++        goto retry_params;
+     }
+ 
+-    if(par.bits == 8 && par.sig == 1)
+-        mDevice->FmtType = DevFmtByte;
+-    else if(par.bits == 8 && par.sig == 0)
+-        mDevice->FmtType = DevFmtUByte;
+-    else if(par.bits == 16 && par.sig == 1)
+-        mDevice->FmtType = DevFmtShort;
+-    else if(par.bits == 16 && par.sig == 0)
+-        mDevice->FmtType = DevFmtUShort;
+-    else if(par.bits == 32 && par.sig == 1)
+-        mDevice->FmtType = DevFmtInt;
+-    else if(par.bits == 32 && par.sig == 0)
+-        mDevice->FmtType = DevFmtUInt;
++    if(par.bps == 1)
++        mDevice->FmtType = (par.sig==1) ? DevFmtByte : DevFmtUByte;
++    else if(par.bps == 2)
++        mDevice->FmtType = (par.sig==1) ? DevFmtShort : DevFmtUShort;
++    else if(par.bps == 4)
++        mDevice->FmtType = (par.sig==1) ? DevFmtInt : DevFmtUInt;
+     else
++        throw al::backend_exception{al::backend_error::DeviceError,
++            "Unhandled sample format: %s %u-bit", (par.sig?"signed":"unsigned"), par.bps*8};
++
++    mFrameStep = par.pchan;
++    if(par.pchan != mDevice->channelsFromFmt())
+     {
+-        ERR("Unhandled sample format: %s %u-bit\n", (par.sig?"signed":"unsigned"), par.bits);
+-        return false;
++        WARN("Got %u channel%s for %s\n", par.pchan, (par.pchan==1)?"":"s",
++            DevFmtChannelsString(mDevice->FmtChans));
++        if(par.pchan < 2) mDevice->FmtChans = DevFmtMono;
++        else mDevice->FmtChans = DevFmtStereo;
+     }
++    mDevice->Frequency = par.rate;
+ 
+     setDefaultChannelOrder();
+ 
diff --git a/srcpkgs/libopenal/patches/use-nonblock-mode-sndio-capture.patch b/srcpkgs/libopenal/patches/use-nonblock-mode-sndio-capture.patch
new file mode 100644
index 000000000000..34520ada3ad1
--- /dev/null
+++ b/srcpkgs/libopenal/patches/use-nonblock-mode-sndio-capture.patch
@@ -0,0 +1,239 @@
+From 1fd4c865fc084f134363db5155361d5483679235 Mon Sep 17 00:00:00 2001
+From: Chris Robinson <chris.kcat@gmail.com>
+Date: Fri, 30 Jul 2021 04:15:00 -0700
+Subject: [PATCH] Use non-block mode for sndio capture
+
+---
+ alc/backends/sndio.cpp | 123 +++++++++++++++++++++++++----------------
+ 1 file changed, 76 insertions(+), 47 deletions(-)
+
+diff --git a/alc/backends/sndio.cpp b/alc/backends/sndio.cpp
+index c41c6c8bc..6852e01a2 100644
+--- a/alc/backends/sndio.cpp
++++ b/alc/backends/sndio.cpp
+@@ -22,6 +22,7 @@
+ 
+ #include "sndio.h"
+ 
++#include <poll.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -166,6 +167,7 @@ bool SndioPlayback::reset()
+     }
+     par.bps = SIO_BPS(par.bits);
+     par.le = SIO_LE_NATIVE;
++    par.msb = 1;
+ 
+     par.rate = mDevice->Frequency;
+     par.pchan = mDevice->channelsFromFmt();
+@@ -197,6 +199,7 @@ bool SndioPlayback::reset()
+     catch(al::backend_exception &e) {
+         if(tryfmt == DevFmtShort)
+             throw;
++        par.clear();
+         tryfmt = DevFmtShort;
+         goto retry_params;
+     }
+@@ -266,6 +269,11 @@ void SndioPlayback::stop()
+ }
+ 
+ 
++/* TODO: This could be improved by avoiding the ring buffer and record thread,
++ * counting the available samples with the sio_onmove callback and reading
++ * directly from the device. However, this depends on reasonable support for
++ * capture buffer sizes apps may request.
++ */
+ struct SndioCapture final : public BackendBase {
+     SndioCapture(DeviceBase *device) noexcept : BackendBase{device} { }
+     ~SndioCapture() override;
+@@ -280,6 +288,7 @@ struct SndioCapture final : public BackendBase {
+ 
+     sio_hdl *mSndHandle{nullptr};
+ 
++    al::vector<struct pollfd> mFds;
+     RingBufferPtr mRing;
+ 
+     std::atomic<bool> mKillNow{true};
+@@ -305,37 +314,53 @@ int SndioCapture::recordProc()
+     while(!mKillNow.load(std::memory_order_acquire)
+         && mDevice->Connected.load(std::memory_order_acquire))
+     {
+-        auto data = mRing->getWriteVector();
+-        size_t todo{data.first.len + data.second.len};
+-        if(todo == 0)
++        /* Wait until there's some samples to read. */
++        const int nfds{sio_pollfd(mSndHandle, mFds.data(), POLLIN)};
++        if(nfds <= 0)
+         {
+-            static char junk[4096];
+-            sio_read(mSndHandle, junk,
+-                minz(sizeof(junk)/frameSize, mDevice->UpdateSize)*frameSize);
++            mDevice->handleDisconnect("Failed to get polling fds: %d", nfds);
++            break;
++        }
++        int pollres{::poll(mFds.data(), static_cast<uint>(nfds), 2000)};
++        if(pollres < 0)
++        {
++            if(errno == EINTR) continue;
++            mDevice->handleDisconnect("Poll error: %s", strerror(errno));
++            break;
++        }
++        if(pollres == 0)
+             continue;
++
++        const int revents{sio_revents(mSndHandle, mFds.data())};
++        if((revents&POLLHUP))
++        {
++            mDevice->handleDisconnect("Got POLLHUP from poll events");
++            break;
+         }
++        if(!(revents&POLLIN))
++            continue;
+ 
+-        size_t total{0u};
+-        data.first.len  *= frameSize;
+-        data.second.len *= frameSize;
+-        todo = minz(todo, mDevice->UpdateSize) * frameSize;
+-        while(total < todo)
++        auto data = mRing->getWriteVector();
++        al::span<al::byte> buffer{data.first.buf, data.first.len*frameSize};
++        while(!buffer.empty())
+         {
+-            if(!data.first.len)
+-                data.first = data.second;
++            size_t got{sio_read(mSndHandle, buffer.data(), buffer.size())};
++            if(got == 0) break;
+ 
+-            size_t got{sio_read(mSndHandle, data.first.buf, minz(todo-total, data.first.len))};
+-            if(!got)
++            mRing->writeAdvance(got / frameSize);
++            buffer = buffer.subspan(got);
++            if(buffer.empty())
+             {
+-                mDevice->handleDisconnect("Failed to read capture samples");
+-                break;
++                data = mRing->getWriteVector();
++                buffer = {data.first.buf, data.first.len*frameSize};
+             }
+-
+-            data.first.buf += got;
+-            data.first.len -= got;
+-            total += got;
+         }
+-        mRing->writeAdvance(total / frameSize);
++        if(buffer.empty())
++        {
++            /* Got samples to read, but no place to store it. Drop it. */
++            static char junk[4096];
++            sio_read(mSndHandle, junk, sizeof(junk) - (sizeof(junk)%frameSize));
++        }
+     }
+ 
+     return 0;
+@@ -350,76 +375,80 @@ void SndioCapture::open(const char *name)
+         throw al::backend_exception{al::backend_error::NoDevice, "Device name \"%s\" not found",
+             name};
+ 
+-    mSndHandle = sio_open(nullptr, SIO_REC, 0);
++    mSndHandle = sio_open(nullptr, SIO_REC, true);
+     if(mSndHandle == nullptr)
+         throw al::backend_exception{al::backend_error::NoDevice, "Could not open backend device"};
+ 
+-    sio_par par;
+-    sio_initpar(&par);
+-
++    SioPar par;
+     switch(mDevice->FmtType)
+     {
+     case DevFmtByte:
+-        par.bps = 1;
++        par.bits = 8;
+         par.sig = 1;
+         break;
+     case DevFmtUByte:
+-        par.bps = 1;
++        par.bits = 8;
+         par.sig = 0;
+         break;
+     case DevFmtShort:
+-        par.bps = 2;
++        par.bits = 16;
+         par.sig = 1;
+         break;
+     case DevFmtUShort:
+-        par.bps = 2;
++        par.bits = 16;
+         par.sig = 0;
+         break;
+     case DevFmtInt:
+-        par.bps = 4;
++        par.bits = 32;
+         par.sig = 1;
+         break;
+     case DevFmtUInt:
+-        par.bps = 4;
++        par.bits = 32;
+         par.sig = 0;
+         break;
+     case DevFmtFloat:
+         throw al::backend_exception{al::backend_error::DeviceError,
+             "%s capture samples not supported", DevFmtTypeString(mDevice->FmtType)};
+     }
+-    par.bits = par.bps * 8;
++    par.bps = SIO_BPS(par.bits);
+     par.le = SIO_LE_NATIVE;
+-    par.msb = SIO_LE_NATIVE ? 0 : 1;
++    par.msb = 1;
+     par.rchan = mDevice->channelsFromFmt();
+     par.rate = mDevice->Frequency;
+ 
+     par.appbufsz = maxu(mDevice->BufferSize, mDevice->Frequency/10);
+-    par.round = minu(par.appbufsz, mDevice->Frequency/40);
+-
+-    mDevice->UpdateSize = par.round;
+-    mDevice->BufferSize = par.appbufsz;
++    par.round = minu(par.appbufsz/2, mDevice->Frequency/40);
+ 
+     if(!sio_setpar(mSndHandle, &par) || !sio_getpar(mSndHandle, &par))
+         throw al::backend_exception{al::backend_error::DeviceError,
+             "Failed to set device praameters"};
+ 
+-    if(par.bits != par.bps*8)
++    if(par.bps > 1 && par.le != SIO_LE_NATIVE)
++        throw al::backend_exception{al::backend_error::DeviceError,
++            "%s-endian samples not supported", par.le ? "Little" : "Big"};
++    if(par.bits < par.bps*8 && !par.msb)
+         throw al::backend_exception{al::backend_error::DeviceError,
+             "Padded samples not supported (got %u of %u bits)", par.bits, par.bps*8};
+ 
+-    if(!((mDevice->FmtType == DevFmtByte && par.bits == 8 && par.sig != 0)
+-        || (mDevice->FmtType == DevFmtUByte && par.bits == 8 && par.sig == 0)
+-        || (mDevice->FmtType == DevFmtShort && par.bits == 16 && par.sig != 0)
+-        || (mDevice->FmtType == DevFmtUShort && par.bits == 16 && par.sig == 0)
+-        || (mDevice->FmtType == DevFmtInt && par.bits == 32 && par.sig != 0)
+-        || (mDevice->FmtType == DevFmtUInt && par.bits == 32 && par.sig == 0))
+-        || mDevice->channelsFromFmt() != par.rchan || mDevice->Frequency != par.rate)
++    auto match_fmt = [](DevFmtType fmttype, const sio_par &par) -> bool
++    {
++        return (fmttype == DevFmtByte && par.bps == 1 && par.sig != 0)
++            || (fmttype == DevFmtUByte && par.bps == 1 && par.sig == 0)
++            || (fmttype == DevFmtShort && par.bps == 2 && par.sig != 0)
++            || (fmttype == DevFmtUShort && par.bps == 2 && par.sig == 0)
++            || (fmttype == DevFmtInt && par.bps == 4 && par.sig != 0)
++            || (fmttype == DevFmtUInt && par.bps == 4 && par.sig == 0);
++    };
++    if(!match_fmt(mDevice->FmtType, par) || mDevice->channelsFromFmt() != par.rchan
++        || mDevice->Frequency != par.rate)
+         throw al::backend_exception{al::backend_error::DeviceError,
+             "Failed to set format %s %s %uhz, got %c%u %u-channel %uhz instead",
+             DevFmtTypeString(mDevice->FmtType), DevFmtChannelsString(mDevice->FmtChans),
+-            mDevice->Frequency, par.sig?'s':'u', par.bits, par.rchan, par.rate};
++            mDevice->Frequency, par.sig?'s':'u', par.bps*8, par.rchan, par.rate};
+ 
+     mRing = RingBuffer::Create(mDevice->BufferSize, par.bps*par.rchan, false);
++    mDevice->BufferSize = static_cast<uint>(mRing->writeSpace());
++    mDevice->UpdateSize = par.round;
+ 
+     setDefaultChannelOrder();
+ 
diff --git a/srcpkgs/libopenal/template b/srcpkgs/libopenal/template
index c89016a3584b..441e138d3c65 100644
--- a/srcpkgs/libopenal/template
+++ b/srcpkgs/libopenal/template
@@ -1,6 +1,6 @@
 # Template file for 'libopenal'
 pkgname=libopenal
-version=1.21.0
+version=1.21.1
 revision=1
 wrksrc="openal-soft-${version}"
 build_style=cmake
@@ -11,9 +11,9 @@ makedepends="zlib-devel alsa-lib-devel pulseaudio-devel SDL2-devel ffmpeg-devel
 short_desc="Cross-platform 3D audio library"
 maintainer="Orphaned <orphan@voidlinux.org>"
 license="LGPL-2.1-or-later"
-homepage="http://openal-soft.org/"
-distfiles="http://openal-soft.org/openal-releases/openal-soft-${version}.tar.bz2"
-checksum=2916b4fc24e23b0271ce0b3468832ad8b6d8441b1830215b28cc4fee6cc89297
+homepage="https://openal-soft.org/"
+distfiles="https://openal-soft.org/openal-releases/openal-soft-${version}.tar.bz2"
+checksum=c8ad767e9a3230df66756a21cc8ebf218a9d47288f2514014832204e666af5d8
 
 build_options="sndio"
 build_options_default="sndio"

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PR PATCH] [Updated] libopenal: update to 1.21.1 and import fixes to sndio backend
  2022-02-13 20:22 [PR PATCH] libopenal: update to 1.21.1 and import fixes to sndio backend mtboehlke
  2022-03-16 19:04 ` [PR PATCH] [Updated] " mtboehlke
@ 2022-04-19 16:15 ` mtboehlke
  2022-04-29 15:45 ` [PR PATCH] [Closed]: " mtboehlke
  2 siblings, 0 replies; 4+ messages in thread
From: mtboehlke @ 2022-04-19 16:15 UTC (permalink / raw)
  To: ml

[-- Attachment #1: Type: text/plain, Size: 1776 bytes --]

There is an updated pull request by mtboehlke against master on the void-packages repository

https://github.com/mtboehlke/void-packages libopenal
https://github.com/void-linux/void-packages/pull/35594

libopenal: update to 1.21.1 and import fixes to sndio backend
Patches to fix the issue reported at https://github.com/kcat/openal-soft/issues/591

<!-- Uncomment relevant sections and delete options which are not applicable -->

#### Testing the changes
- I tested the changes in this PR: **briefly**

<!--
#### New package
- This new package conforms to the [quality requirements](https://github.com/void-linux/void-packages/blob/master/Manual.md#quality-requirements): **YES**|**NO**
-->

<!-- Note: If the build is likely to take more than 2 hours, please [skip CI](https://github.com/void-linux/void-packages/blob/master/CONTRIBUTING.md#continuous-integration)
and test at least one native build and, if supported, at least one cross build.
Ignore this section if this PR is not skipping CI.
-->
<!-- 
#### Local build testing
- I built this PR locally for my native architecture, (ARCH-LIBC)
- I built this PR locally for these architectures (if supported. mark crossbuilds):
  - aarch64-musl
  - armv7l
  - armv6l-musl
-->
I encountered the problem described in the linked issue when playing around with wildmidi.  I was hoping to have wildmidi use sndio by compiling without direct alsa support, and then rely on libopenal to use sndio.  When libopenal was configured for sndio, playback stopped immediately with the error message: `[ALSOFT] (EE) Error stopping device`.  Playback worked as expected with sndio after including these upstream patches.

A patch file from https://github.com/void-linux/void-packages/pull/35594.patch is attached

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: github-pr-libopenal-35594.patch --]
[-- Type: text/x-diff, Size: 20003 bytes --]

From b931148fd5ac092c099f2a7428423382172d2fb1 Mon Sep 17 00:00:00 2001
From: Mat Boehlke <mtboehlke@gmail.com>
Date: Sun, 13 Feb 2022 13:59:19 -0600
Subject: [PATCH] libopenal: update to 1.21.1 and import fixes to sndio backend

Patches to fix the issue reported at https://github.com/kcat/openal-soft/issues/591
---
 .../sndio-simplify-channel-handling.patch     | 242 ++++++++++++++++++
 .../use-nonblock-mode-sndio-capture.patch     | 239 +++++++++++++++++
 srcpkgs/libopenal/template                    |   8 +-
 3 files changed, 485 insertions(+), 4 deletions(-)
 create mode 100644 srcpkgs/libopenal/patches/sndio-simplify-channel-handling.patch
 create mode 100644 srcpkgs/libopenal/patches/use-nonblock-mode-sndio-capture.patch

diff --git a/srcpkgs/libopenal/patches/sndio-simplify-channel-handling.patch b/srcpkgs/libopenal/patches/sndio-simplify-channel-handling.patch
new file mode 100644
index 000000000000..909943e4e22f
--- /dev/null
+++ b/srcpkgs/libopenal/patches/sndio-simplify-channel-handling.patch
@@ -0,0 +1,242 @@
+From 620836f173ae6fc4505d0634984e0f2c46166367 Mon Sep 17 00:00:00 2001
+From: Chris Robinson <chris.kcat@gmail.com>
+Date: Thu, 29 Jul 2021 21:07:20 -0700
+Subject: [PATCH] Simplify channel handling in the sndio backend
+
+---
+ alc/backends/sndio.cpp | 152 +++++++++++++++++------------------------
+ 1 file changed, 63 insertions(+), 89 deletions(-)
+
+diff --git a/alc/backends/sndio.cpp b/alc/backends/sndio.cpp
+index 2d8b424c9..c41c6c8bc 100644
+--- a/alc/backends/sndio.cpp
++++ b/alc/backends/sndio.cpp
+@@ -44,6 +44,11 @@ namespace {
+ 
+ static const char sndio_device[] = "SndIO Default";
+ 
++struct SioPar : public sio_par {
++    SioPar() { sio_initpar(this); }
++
++    void clear() { sio_initpar(this); }
++};
+ 
+ struct SndioPlayback final : public BackendBase {
+     SndioPlayback(DeviceBase *device) noexcept : BackendBase{device} { }
+@@ -57,6 +62,7 @@ struct SndioPlayback final : public BackendBase {
+     void stop() override;
+ 
+     sio_hdl *mSndHandle{nullptr};
++    uint mFrameStep{};
+ 
+     al::vector<al::byte> mBuffer;
+ 
+@@ -75,16 +81,8 @@ SndioPlayback::~SndioPlayback()
+ 
+ int SndioPlayback::mixerProc()
+ {
+-    sio_par par;
+-    sio_initpar(&par);
+-    if(!sio_getpar(mSndHandle, &par))
+-    {
+-        mDevice->handleDisconnect("Failed to get device parameters");
+-        return 1;
+-    }
+-
+-    const size_t frameStep{par.pchan};
+-    const size_t frameSize{frameStep * par.bps};
++    const size_t frameStep{mFrameStep};
++    const size_t frameSize{frameStep * mDevice->bytesFromFmt()};
+ 
+     SetRTPriority();
+     althrd_setname(MIXER_THREAD_NAME);
+@@ -92,22 +90,20 @@ int SndioPlayback::mixerProc()
+     while(!mKillNow.load(std::memory_order_acquire)
+         && mDevice->Connected.load(std::memory_order_acquire))
+     {
+-        al::byte *WritePtr{mBuffer.data()};
+-        size_t len{mBuffer.size()};
++        al::span<al::byte> buffer{mBuffer};
+ 
+-        mDevice->renderSamples(WritePtr, static_cast<uint>(len/frameSize), frameStep);
+-        while(len > 0 && !mKillNow.load(std::memory_order_acquire))
++        mDevice->renderSamples(buffer.data(), static_cast<uint>(buffer.size() / frameSize),
++            frameStep);
++        while(!buffer.empty() && !mKillNow.load(std::memory_order_acquire))
+         {
+-            size_t wrote{sio_write(mSndHandle, WritePtr, len)};
++            size_t wrote{sio_write(mSndHandle, buffer.data(), buffer.size())};
+             if(wrote == 0)
+             {
+                 ERR("sio_write failed\n");
+                 mDevice->handleDisconnect("Failed to write playback samples");
+                 break;
+             }
+-
+-            len -= wrote;
+-            WritePtr += wrote;
++            buffer = buffer.subspan(wrote);
+         }
+     }
+ 
+@@ -136,25 +132,11 @@ void SndioPlayback::open(const char *name)
+ 
+ bool SndioPlayback::reset()
+ {
+-    sio_par par;
+-    sio_initpar(&par);
++    SioPar par;
+ 
+-    par.rate = mDevice->Frequency;
+-    switch(mDevice->FmtChans)
+-    {
+-    case DevFmtMono   : par.pchan = 1; break;
+-    case DevFmtQuad   : par.pchan = 4; break;
+-    case DevFmtX51Rear: // fall-through - "Similar to 5.1, except using rear channels instead of sides"
+-    case DevFmtX51    : par.pchan = 6; break;
+-    case DevFmtX61    : par.pchan = 7; break;
+-    case DevFmtX71    : par.pchan = 8; break;
+-
+-    // fall back to stereo for Ambi3D
+-    case DevFmtAmbi3D : // fall-through
+-    case DevFmtStereo : par.pchan = 2; break;
+-    }
+-
+-    switch(mDevice->FmtType)
++    auto tryfmt = mDevice->FmtType;
++retry_params:
++    switch(tryfmt)
+     {
+     case DevFmtByte:
+         par.bits = 8;
+@@ -164,7 +146,6 @@ bool SndioPlayback::reset()
+         par.bits = 8;
+         par.sig = 0;
+         break;
+-    case DevFmtFloat:
+     case DevFmtShort:
+         par.bits = 16;
+         par.sig = 1;
+@@ -173,6 +154,7 @@ bool SndioPlayback::reset()
+         par.bits = 16;
+         par.sig = 0;
+         break;
++    case DevFmtFloat:
+     case DevFmtInt:
+         par.bits = 32;
+         par.sig = 1;
+@@ -182,70 +164,62 @@ bool SndioPlayback::reset()
+         par.sig = 0;
+         break;
+     }
++    par.bps = SIO_BPS(par.bits);
+     par.le = SIO_LE_NATIVE;
+ 
++    par.rate = mDevice->Frequency;
++    par.pchan = mDevice->channelsFromFmt();
++
+     par.round = mDevice->UpdateSize;
+     par.appbufsz = mDevice->BufferSize - mDevice->UpdateSize;
+     if(!par.appbufsz) par.appbufsz = mDevice->UpdateSize;
+ 
+-    if(!sio_setpar(mSndHandle, &par) || !sio_getpar(mSndHandle, &par))
+-    {
+-        ERR("Failed to set device parameters\n");
+-        return false;
+-    }
+-
+-    if(par.bits != par.bps*8)
+-    {
+-        ERR("Padded samples not supported (%u of %u bits)\n", par.bits, par.bps*8);
+-        return false;
+-    }
+-    if(par.le != SIO_LE_NATIVE)
+-    {
+-        ERR("Non-native-endian samples not supported (got %s-endian)\n",
+-            par.le ? "little" : "big");
+-        return false;
+-    }
+-
+-    mDevice->Frequency = par.rate;
+-
+-    if(par.pchan < 2)
+-    {
+-        if(mDevice->FmtChans != DevFmtMono)
+-        {
+-            WARN("Got %u channel for %s\n", par.pchan, DevFmtChannelsString(mDevice->FmtChans));
+-            mDevice->FmtChans = DevFmtMono;
+-        }
++    try {
++        if(!sio_setpar(mSndHandle, &par))
++            throw al::backend_exception{al::backend_error::DeviceError,
++                "Failed to set device parameters"};
++
++        par.clear();
++        if(!sio_getpar(mSndHandle, &par))
++            throw al::backend_exception{al::backend_error::DeviceError,
++                "Failed to get device parameters"};
++
++        if(par.bps > 1 && par.le != SIO_LE_NATIVE)
++            throw al::backend_exception{al::backend_error::DeviceError,
++                "%s-endian samples not supported", par.le ? "Little" : "Big"};
++        if(par.bits < par.bps*8 && !par.msb)
++            throw al::backend_exception{al::backend_error::DeviceError,
++                "MSB-padded samples not supported (%u of %u bits)", par.bits, par.bps*8};
++        if(par.pchan < 1)
++            throw al::backend_exception{al::backend_error::DeviceError,
++                "No playback channels on device"};
+     }
+-    else if((par.pchan == 2 && mDevice->FmtChans != DevFmtStereo)
+-        || par.pchan == 3
+-        || (par.pchan == 4 && mDevice->FmtChans != DevFmtQuad)
+-        || par.pchan == 5
+-        || (par.pchan == 6 && mDevice->FmtChans != DevFmtX51 && mDevice->FmtChans != DevFmtX51Rear)
+-        || (par.pchan == 7 && mDevice->FmtChans != DevFmtX61)
+-        || (par.pchan == 8 && mDevice->FmtChans != DevFmtX71)
+-        || par.pchan > 8)
+-    {
+-        WARN("Got %u channels for %s\n", par.pchan, DevFmtChannelsString(mDevice->FmtChans));
+-        mDevice->FmtChans = DevFmtStereo;
++    catch(al::backend_exception &e) {
++        if(tryfmt == DevFmtShort)
++            throw;
++        tryfmt = DevFmtShort;
++        goto retry_params;
+     }
+ 
+-    if(par.bits == 8 && par.sig == 1)
+-        mDevice->FmtType = DevFmtByte;
+-    else if(par.bits == 8 && par.sig == 0)
+-        mDevice->FmtType = DevFmtUByte;
+-    else if(par.bits == 16 && par.sig == 1)
+-        mDevice->FmtType = DevFmtShort;
+-    else if(par.bits == 16 && par.sig == 0)
+-        mDevice->FmtType = DevFmtUShort;
+-    else if(par.bits == 32 && par.sig == 1)
+-        mDevice->FmtType = DevFmtInt;
+-    else if(par.bits == 32 && par.sig == 0)
+-        mDevice->FmtType = DevFmtUInt;
++    if(par.bps == 1)
++        mDevice->FmtType = (par.sig==1) ? DevFmtByte : DevFmtUByte;
++    else if(par.bps == 2)
++        mDevice->FmtType = (par.sig==1) ? DevFmtShort : DevFmtUShort;
++    else if(par.bps == 4)
++        mDevice->FmtType = (par.sig==1) ? DevFmtInt : DevFmtUInt;
+     else
++        throw al::backend_exception{al::backend_error::DeviceError,
++            "Unhandled sample format: %s %u-bit", (par.sig?"signed":"unsigned"), par.bps*8};
++
++    mFrameStep = par.pchan;
++    if(par.pchan != mDevice->channelsFromFmt())
+     {
+-        ERR("Unhandled sample format: %s %u-bit\n", (par.sig?"signed":"unsigned"), par.bits);
+-        return false;
++        WARN("Got %u channel%s for %s\n", par.pchan, (par.pchan==1)?"":"s",
++            DevFmtChannelsString(mDevice->FmtChans));
++        if(par.pchan < 2) mDevice->FmtChans = DevFmtMono;
++        else mDevice->FmtChans = DevFmtStereo;
+     }
++    mDevice->Frequency = par.rate;
+ 
+     setDefaultChannelOrder();
+ 
diff --git a/srcpkgs/libopenal/patches/use-nonblock-mode-sndio-capture.patch b/srcpkgs/libopenal/patches/use-nonblock-mode-sndio-capture.patch
new file mode 100644
index 000000000000..34520ada3ad1
--- /dev/null
+++ b/srcpkgs/libopenal/patches/use-nonblock-mode-sndio-capture.patch
@@ -0,0 +1,239 @@
+From 1fd4c865fc084f134363db5155361d5483679235 Mon Sep 17 00:00:00 2001
+From: Chris Robinson <chris.kcat@gmail.com>
+Date: Fri, 30 Jul 2021 04:15:00 -0700
+Subject: [PATCH] Use non-block mode for sndio capture
+
+---
+ alc/backends/sndio.cpp | 123 +++++++++++++++++++++++++----------------
+ 1 file changed, 76 insertions(+), 47 deletions(-)
+
+diff --git a/alc/backends/sndio.cpp b/alc/backends/sndio.cpp
+index c41c6c8bc..6852e01a2 100644
+--- a/alc/backends/sndio.cpp
++++ b/alc/backends/sndio.cpp
+@@ -22,6 +22,7 @@
+ 
+ #include "sndio.h"
+ 
++#include <poll.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+@@ -166,6 +167,7 @@ bool SndioPlayback::reset()
+     }
+     par.bps = SIO_BPS(par.bits);
+     par.le = SIO_LE_NATIVE;
++    par.msb = 1;
+ 
+     par.rate = mDevice->Frequency;
+     par.pchan = mDevice->channelsFromFmt();
+@@ -197,6 +199,7 @@ bool SndioPlayback::reset()
+     catch(al::backend_exception &e) {
+         if(tryfmt == DevFmtShort)
+             throw;
++        par.clear();
+         tryfmt = DevFmtShort;
+         goto retry_params;
+     }
+@@ -266,6 +269,11 @@ void SndioPlayback::stop()
+ }
+ 
+ 
++/* TODO: This could be improved by avoiding the ring buffer and record thread,
++ * counting the available samples with the sio_onmove callback and reading
++ * directly from the device. However, this depends on reasonable support for
++ * capture buffer sizes apps may request.
++ */
+ struct SndioCapture final : public BackendBase {
+     SndioCapture(DeviceBase *device) noexcept : BackendBase{device} { }
+     ~SndioCapture() override;
+@@ -280,6 +288,7 @@ struct SndioCapture final : public BackendBase {
+ 
+     sio_hdl *mSndHandle{nullptr};
+ 
++    al::vector<struct pollfd> mFds;
+     RingBufferPtr mRing;
+ 
+     std::atomic<bool> mKillNow{true};
+@@ -305,37 +314,53 @@ int SndioCapture::recordProc()
+     while(!mKillNow.load(std::memory_order_acquire)
+         && mDevice->Connected.load(std::memory_order_acquire))
+     {
+-        auto data = mRing->getWriteVector();
+-        size_t todo{data.first.len + data.second.len};
+-        if(todo == 0)
++        /* Wait until there's some samples to read. */
++        const int nfds{sio_pollfd(mSndHandle, mFds.data(), POLLIN)};
++        if(nfds <= 0)
+         {
+-            static char junk[4096];
+-            sio_read(mSndHandle, junk,
+-                minz(sizeof(junk)/frameSize, mDevice->UpdateSize)*frameSize);
++            mDevice->handleDisconnect("Failed to get polling fds: %d", nfds);
++            break;
++        }
++        int pollres{::poll(mFds.data(), static_cast<uint>(nfds), 2000)};
++        if(pollres < 0)
++        {
++            if(errno == EINTR) continue;
++            mDevice->handleDisconnect("Poll error: %s", strerror(errno));
++            break;
++        }
++        if(pollres == 0)
+             continue;
++
++        const int revents{sio_revents(mSndHandle, mFds.data())};
++        if((revents&POLLHUP))
++        {
++            mDevice->handleDisconnect("Got POLLHUP from poll events");
++            break;
+         }
++        if(!(revents&POLLIN))
++            continue;
+ 
+-        size_t total{0u};
+-        data.first.len  *= frameSize;
+-        data.second.len *= frameSize;
+-        todo = minz(todo, mDevice->UpdateSize) * frameSize;
+-        while(total < todo)
++        auto data = mRing->getWriteVector();
++        al::span<al::byte> buffer{data.first.buf, data.first.len*frameSize};
++        while(!buffer.empty())
+         {
+-            if(!data.first.len)
+-                data.first = data.second;
++            size_t got{sio_read(mSndHandle, buffer.data(), buffer.size())};
++            if(got == 0) break;
+ 
+-            size_t got{sio_read(mSndHandle, data.first.buf, minz(todo-total, data.first.len))};
+-            if(!got)
++            mRing->writeAdvance(got / frameSize);
++            buffer = buffer.subspan(got);
++            if(buffer.empty())
+             {
+-                mDevice->handleDisconnect("Failed to read capture samples");
+-                break;
++                data = mRing->getWriteVector();
++                buffer = {data.first.buf, data.first.len*frameSize};
+             }
+-
+-            data.first.buf += got;
+-            data.first.len -= got;
+-            total += got;
+         }
+-        mRing->writeAdvance(total / frameSize);
++        if(buffer.empty())
++        {
++            /* Got samples to read, but no place to store it. Drop it. */
++            static char junk[4096];
++            sio_read(mSndHandle, junk, sizeof(junk) - (sizeof(junk)%frameSize));
++        }
+     }
+ 
+     return 0;
+@@ -350,76 +375,80 @@ void SndioCapture::open(const char *name)
+         throw al::backend_exception{al::backend_error::NoDevice, "Device name \"%s\" not found",
+             name};
+ 
+-    mSndHandle = sio_open(nullptr, SIO_REC, 0);
++    mSndHandle = sio_open(nullptr, SIO_REC, true);
+     if(mSndHandle == nullptr)
+         throw al::backend_exception{al::backend_error::NoDevice, "Could not open backend device"};
+ 
+-    sio_par par;
+-    sio_initpar(&par);
+-
++    SioPar par;
+     switch(mDevice->FmtType)
+     {
+     case DevFmtByte:
+-        par.bps = 1;
++        par.bits = 8;
+         par.sig = 1;
+         break;
+     case DevFmtUByte:
+-        par.bps = 1;
++        par.bits = 8;
+         par.sig = 0;
+         break;
+     case DevFmtShort:
+-        par.bps = 2;
++        par.bits = 16;
+         par.sig = 1;
+         break;
+     case DevFmtUShort:
+-        par.bps = 2;
++        par.bits = 16;
+         par.sig = 0;
+         break;
+     case DevFmtInt:
+-        par.bps = 4;
++        par.bits = 32;
+         par.sig = 1;
+         break;
+     case DevFmtUInt:
+-        par.bps = 4;
++        par.bits = 32;
+         par.sig = 0;
+         break;
+     case DevFmtFloat:
+         throw al::backend_exception{al::backend_error::DeviceError,
+             "%s capture samples not supported", DevFmtTypeString(mDevice->FmtType)};
+     }
+-    par.bits = par.bps * 8;
++    par.bps = SIO_BPS(par.bits);
+     par.le = SIO_LE_NATIVE;
+-    par.msb = SIO_LE_NATIVE ? 0 : 1;
++    par.msb = 1;
+     par.rchan = mDevice->channelsFromFmt();
+     par.rate = mDevice->Frequency;
+ 
+     par.appbufsz = maxu(mDevice->BufferSize, mDevice->Frequency/10);
+-    par.round = minu(par.appbufsz, mDevice->Frequency/40);
+-
+-    mDevice->UpdateSize = par.round;
+-    mDevice->BufferSize = par.appbufsz;
++    par.round = minu(par.appbufsz/2, mDevice->Frequency/40);
+ 
+     if(!sio_setpar(mSndHandle, &par) || !sio_getpar(mSndHandle, &par))
+         throw al::backend_exception{al::backend_error::DeviceError,
+             "Failed to set device praameters"};
+ 
+-    if(par.bits != par.bps*8)
++    if(par.bps > 1 && par.le != SIO_LE_NATIVE)
++        throw al::backend_exception{al::backend_error::DeviceError,
++            "%s-endian samples not supported", par.le ? "Little" : "Big"};
++    if(par.bits < par.bps*8 && !par.msb)
+         throw al::backend_exception{al::backend_error::DeviceError,
+             "Padded samples not supported (got %u of %u bits)", par.bits, par.bps*8};
+ 
+-    if(!((mDevice->FmtType == DevFmtByte && par.bits == 8 && par.sig != 0)
+-        || (mDevice->FmtType == DevFmtUByte && par.bits == 8 && par.sig == 0)
+-        || (mDevice->FmtType == DevFmtShort && par.bits == 16 && par.sig != 0)
+-        || (mDevice->FmtType == DevFmtUShort && par.bits == 16 && par.sig == 0)
+-        || (mDevice->FmtType == DevFmtInt && par.bits == 32 && par.sig != 0)
+-        || (mDevice->FmtType == DevFmtUInt && par.bits == 32 && par.sig == 0))
+-        || mDevice->channelsFromFmt() != par.rchan || mDevice->Frequency != par.rate)
++    auto match_fmt = [](DevFmtType fmttype, const sio_par &par) -> bool
++    {
++        return (fmttype == DevFmtByte && par.bps == 1 && par.sig != 0)
++            || (fmttype == DevFmtUByte && par.bps == 1 && par.sig == 0)
++            || (fmttype == DevFmtShort && par.bps == 2 && par.sig != 0)
++            || (fmttype == DevFmtUShort && par.bps == 2 && par.sig == 0)
++            || (fmttype == DevFmtInt && par.bps == 4 && par.sig != 0)
++            || (fmttype == DevFmtUInt && par.bps == 4 && par.sig == 0);
++    };
++    if(!match_fmt(mDevice->FmtType, par) || mDevice->channelsFromFmt() != par.rchan
++        || mDevice->Frequency != par.rate)
+         throw al::backend_exception{al::backend_error::DeviceError,
+             "Failed to set format %s %s %uhz, got %c%u %u-channel %uhz instead",
+             DevFmtTypeString(mDevice->FmtType), DevFmtChannelsString(mDevice->FmtChans),
+-            mDevice->Frequency, par.sig?'s':'u', par.bits, par.rchan, par.rate};
++            mDevice->Frequency, par.sig?'s':'u', par.bps*8, par.rchan, par.rate};
+ 
+     mRing = RingBuffer::Create(mDevice->BufferSize, par.bps*par.rchan, false);
++    mDevice->BufferSize = static_cast<uint>(mRing->writeSpace());
++    mDevice->UpdateSize = par.round;
+ 
+     setDefaultChannelOrder();
+ 
diff --git a/srcpkgs/libopenal/template b/srcpkgs/libopenal/template
index c89016a3584b..441e138d3c65 100644
--- a/srcpkgs/libopenal/template
+++ b/srcpkgs/libopenal/template
@@ -1,6 +1,6 @@
 # Template file for 'libopenal'
 pkgname=libopenal
-version=1.21.0
+version=1.21.1
 revision=1
 wrksrc="openal-soft-${version}"
 build_style=cmake
@@ -11,9 +11,9 @@ makedepends="zlib-devel alsa-lib-devel pulseaudio-devel SDL2-devel ffmpeg-devel
 short_desc="Cross-platform 3D audio library"
 maintainer="Orphaned <orphan@voidlinux.org>"
 license="LGPL-2.1-or-later"
-homepage="http://openal-soft.org/"
-distfiles="http://openal-soft.org/openal-releases/openal-soft-${version}.tar.bz2"
-checksum=2916b4fc24e23b0271ce0b3468832ad8b6d8441b1830215b28cc4fee6cc89297
+homepage="https://openal-soft.org/"
+distfiles="https://openal-soft.org/openal-releases/openal-soft-${version}.tar.bz2"
+checksum=c8ad767e9a3230df66756a21cc8ebf218a9d47288f2514014832204e666af5d8
 
 build_options="sndio"
 build_options_default="sndio"

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PR PATCH] [Closed]: libopenal: update to 1.21.1 and import fixes to sndio backend
  2022-02-13 20:22 [PR PATCH] libopenal: update to 1.21.1 and import fixes to sndio backend mtboehlke
  2022-03-16 19:04 ` [PR PATCH] [Updated] " mtboehlke
  2022-04-19 16:15 ` mtboehlke
@ 2022-04-29 15:45 ` mtboehlke
  2 siblings, 0 replies; 4+ messages in thread
From: mtboehlke @ 2022-04-29 15:45 UTC (permalink / raw)
  To: ml

[-- Attachment #1: Type: text/plain, Size: 1614 bytes --]

There's a closed pull request on the void-packages repository

libopenal: update to 1.21.1 and import fixes to sndio backend
https://github.com/void-linux/void-packages/pull/35594

Description:
Patches to fix the issue reported at https://github.com/kcat/openal-soft/issues/591

<!-- Uncomment relevant sections and delete options which are not applicable -->

#### Testing the changes
- I tested the changes in this PR: **briefly**

<!--
#### New package
- This new package conforms to the [quality requirements](https://github.com/void-linux/void-packages/blob/master/Manual.md#quality-requirements): **YES**|**NO**
-->

<!-- Note: If the build is likely to take more than 2 hours, please [skip CI](https://github.com/void-linux/void-packages/blob/master/CONTRIBUTING.md#continuous-integration)
and test at least one native build and, if supported, at least one cross build.
Ignore this section if this PR is not skipping CI.
-->
<!-- 
#### Local build testing
- I built this PR locally for my native architecture, (ARCH-LIBC)
- I built this PR locally for these architectures (if supported. mark crossbuilds):
  - aarch64-musl
  - armv7l
  - armv6l-musl
-->
I encountered the problem described in the linked issue when playing around with wildmidi.  I was hoping to have wildmidi use sndio by compiling without direct alsa support, and then rely on libopenal to use sndio.  When libopenal was configured for sndio, playback stopped immediately with the error message: `[ALSOFT] (EE) Error stopping device`.  Playback worked as expected with sndio after including these upstream patches.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-04-29 15:45 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-13 20:22 [PR PATCH] libopenal: update to 1.21.1 and import fixes to sndio backend mtboehlke
2022-03-16 19:04 ` [PR PATCH] [Updated] " mtboehlke
2022-04-19 16:15 ` mtboehlke
2022-04-29 15:45 ` [PR PATCH] [Closed]: " mtboehlke

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).