aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--alc/backends/sndio.cpp139
1 files changed, 78 insertions, 61 deletions
diff --git a/alc/backends/sndio.cpp b/alc/backends/sndio.cpp
index f51f508f..90233a89 100644
--- a/alc/backends/sndio.cpp
+++ b/alc/backends/sndio.cpp
@@ -58,7 +58,7 @@ struct SndioPlayback final : public BackendBase {
sio_hdl *mSndHandle{nullptr};
- al::vector<ALubyte> mBuffer;
+ al::vector<al::byte> mBuffer;
std::atomic<bool> mKillNow{true};
std::thread mThread;
@@ -75,19 +75,27 @@ SndioPlayback::~SndioPlayback()
int SndioPlayback::mixerProc()
{
+ sio_par par;
+ sio_initpar(&par);
+ if(!sio_getpar(mSndHandle, &par))
+ {
+ aluHandleDisconnect(mDevice, "Failed to get device parameters");
+ return 1;
+ }
+
+ const size_t frameStep{par.pchan};
+ const size_t frameSize{frameStep * par.bps};
+
SetRTPriority();
althrd_setname(MIXER_THREAD_NAME);
- const size_t frameStep{mDevice->channelsFromFmt()};
- const ALuint frameSize{mDevice->frameSizeFromFmt()};
-
- while(!mKillNow.load(std::memory_order_acquire) &&
- mDevice->Connected.load(std::memory_order_acquire))
+ while(!mKillNow.load(std::memory_order_acquire)
+ && mDevice->Connected.load(std::memory_order_acquire))
{
- ALubyte *WritePtr{mBuffer.data()};
+ al::byte *WritePtr{mBuffer.data()};
size_t len{mBuffer.size()};
- aluMixData(mDevice, WritePtr, static_cast<ALuint>(len/frameSize), frameStep);
+ aluMixData(mDevice, WritePtr, static_cast<ALuint>(len)/frameSize, frameStep);
while(len > 0 && !mKillNow.load(std::memory_order_acquire))
{
size_t wrote{sio_write(mSndHandle, WritePtr, len)};
@@ -129,47 +137,45 @@ bool SndioPlayback::reset()
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;
-
- case DevFmtStereo : // fall-through
- default: // fall back to stereo for all unknown formats and Ambi3D
- mDevice->FmtChans = DevFmtStereo;
- par.pchan = 2;
- break;
+ 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)
{
- case DevFmtByte:
- par.bits = 8;
- par.sig = 1;
- break;
- case DevFmtUByte:
- par.bits = 8;
- par.sig = 0;
- break;
- case DevFmtFloat:
- case DevFmtShort:
- par.bits = 16;
- par.sig = 1;
- break;
- case DevFmtUShort:
- par.bits = 16;
- par.sig = 0;
- break;
- case DevFmtInt:
- par.bits = 32;
- par.sig = 1;
- break;
- case DevFmtUInt:
- par.bits = 32;
- par.sig = 0;
- break;
+ case DevFmtByte:
+ par.bits = 8;
+ par.sig = 1;
+ break;
+ case DevFmtUByte:
+ par.bits = 8;
+ par.sig = 0;
+ break;
+ case DevFmtFloat:
+ case DevFmtShort:
+ par.bits = 16;
+ par.sig = 1;
+ break;
+ case DevFmtUShort:
+ par.bits = 16;
+ par.sig = 0;
+ break;
+ case DevFmtInt:
+ par.bits = 32;
+ par.sig = 1;
+ break;
+ case DevFmtUInt:
+ par.bits = 32;
+ par.sig = 0;
+ break;
}
par.le = SIO_LE_NATIVE;
@@ -191,21 +197,25 @@ bool SndioPlayback::reset()
mDevice->Frequency = par.rate;
- switch(par.pchan)
+ if(par.pchan < 2)
+ {
+ if(mDevice->FmtChans != DevFmtMono)
+ {
+ WARN("Got %u channel for %s\n", par.pchan, DevFmtChannelsString(mDevice->FmtChans));
+ mDevice->FmtChans = DevFmtMono;
+ }
+ }
+ 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)
{
- case 1: mDevice->FmtChans = DevFmtMono; break;
- case 2: mDevice->FmtChans = DevFmtStereo; break;
- case 4: mDevice->FmtChans = DevFmtQuad; break;
- case 6:
- if(mDevice->FmtChans != DevFmtX51Rear) // if it's already DevFmtX51Rear no change is needed
- mDevice->FmtChans = DevFmtX51;
- break;
- case 7: mDevice->FmtChans = DevFmtX61; break;
- case 8: mDevice->FmtChans = DevFmtX71; break;
-
- default:
- ERR("Unexpected number of channels: %d\n", par.pchan);
- return ALC_FALSE;
+ WARN("Got %u channels for %s\n", par.pchan, DevFmtChannelsString(mDevice->FmtChans));
+ mDevice->FmtChans = DevFmtStereo;
}
if(par.bits == 8 && par.sig == 1)
@@ -231,8 +241,15 @@ bool SndioPlayback::reset()
mDevice->UpdateSize = par.round;
mDevice->BufferSize = par.bufsz + par.round;
- mBuffer.resize(mDevice->UpdateSize * mDevice->frameSizeFromFmt());
- std::fill(mBuffer.begin(), mBuffer.end(), 0);
+ mBuffer.resize(mDevice->UpdateSize * par.pchan*par.bps);
+ if(par.sig == 1)
+ std::fill(mBuffer.begin(), mBuffer.end(), al::byte{});
+ else if(par.bits == 8)
+ std::fill_n(mBuffer.data(), mBuffer.size(), al::byte(0x80));
+ else if(par.bits == 16)
+ std::fill_n(reinterpret_cast<uint16_t*>(mBuffer.data()), mBuffer.size()/2, 0x8000);
+ else if(par.bits == 32)
+ std::fill_n(reinterpret_cast<uint32_t*>(mBuffer.data()), mBuffer.size()/4, 0x80000000u);
return true;
}