aboutsummaryrefslogtreecommitdiffstats
path: root/alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2019-12-21 20:43:46 -0800
committerChris Robinson <[email protected]>2019-12-21 20:43:46 -0800
commit2e6a55a87ce24a9303c3039609b41fb0eb302483 (patch)
treef3bb706cac1689ac9233da4bdd78a9530b5c078a /alc
parentc2ca617ed60e26878a6ac10aaf0dc644b6a24d29 (diff)
Handle padding between device sample frames
The padding must be constant and sample type aligned (e.g. some fixed multiple of two bytes between the start of two consecutive frames for 16-bit output). The intent is to always have the ability for stereo output with WASAPI even if the device has some other unsupported configuration, as long as front-left and front-right exist.
Diffstat (limited to 'alc')
-rw-r--r--alc/alc.cpp2
-rw-r--r--alc/alu.cpp34
-rw-r--r--alc/alu.h3
-rw-r--r--alc/backends/alsa.cpp6
-rw-r--r--alc/backends/coreaudio.cpp3
-rw-r--r--alc/backends/dsound.cpp5
-rw-r--r--alc/backends/jack.cpp6
-rw-r--r--alc/backends/null.cpp2
-rw-r--r--alc/backends/opensl.cpp6
-rw-r--r--alc/backends/oss.cpp3
-rw-r--r--alc/backends/portaudio.cpp3
-rw-r--r--alc/backends/pulseaudio.cpp2
-rw-r--r--alc/backends/sdl2.cpp2
-rw-r--r--alc/backends/sndio.cpp3
-rw-r--r--alc/backends/solaris.cpp3
-rw-r--r--alc/backends/wasapi.cpp43
-rw-r--r--alc/backends/wave.cpp3
-rw-r--r--alc/backends/winmm.cpp4
18 files changed, 78 insertions, 55 deletions
diff --git a/alc/alc.cpp b/alc/alc.cpp
index 9287302e..d9578b9d 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -4144,7 +4144,7 @@ START_API_FUNC
else
{
BackendLockGuard _{*dev->Backend};
- aluMixData(dev.get(), buffer, static_cast<ALuint>(samples));
+ aluMixData(dev.get(), buffer, static_cast<ALuint>(samples), dev->channelsFromFmt());
}
}
END_API_FUNC
diff --git a/alc/alu.cpp b/alc/alu.cpp
index ef6b2ed7..fc3555bf 100644
--- a/alc/alu.cpp
+++ b/alc/alu.cpp
@@ -1861,22 +1861,21 @@ template<> inline uint8_t SampleConv(float val) noexcept
template<DevFmtType T>
void Write(const al::span<const FloatBufferLine> InBuffer, void *OutBuffer, const size_t Offset,
- const ALuint SamplesToDo)
+ const ALuint SamplesToDo, const size_t FrameStep)
{
using SampleType = typename DevFmtTypeTraits<T>::Type;
- const size_t numchans{InBuffer.size()};
- ASSUME(numchans > 0);
+ ASSUME(FrameStep > 0);
- SampleType *outbase = static_cast<SampleType*>(OutBuffer) + Offset*numchans;
- auto conv_channel = [&outbase,SamplesToDo,numchans](const FloatBufferLine &inbuf) -> void
+ SampleType *outbase = static_cast<SampleType*>(OutBuffer) + Offset*FrameStep;
+ auto conv_channel = [&outbase,SamplesToDo,FrameStep](const FloatBufferLine &inbuf) -> void
{
ASSUME(SamplesToDo > 0);
SampleType *out{outbase++};
- auto conv_sample = [numchans,&out](const float s) noexcept -> void
+ auto conv_sample = [FrameStep,&out](const float s) noexcept -> void
{
*out = SampleConv<SampleType>(s);
- out += numchans;
+ out += FrameStep;
};
std::for_each(inbuf.begin(), inbuf.begin()+SamplesToDo, conv_sample);
};
@@ -1885,7 +1884,8 @@ void Write(const al::span<const FloatBufferLine> InBuffer, void *OutBuffer, cons
} // namespace
-void aluMixData(ALCdevice *device, ALvoid *OutBuffer, const ALuint NumSamples)
+void aluMixData(ALCdevice *device, void *OutBuffer, const ALuint NumSamples,
+ const size_t FrameStep)
{
FPUCtl mixer_mode{};
for(ALuint SamplesDone{0u};SamplesDone < NumSamples;)
@@ -1956,15 +1956,15 @@ void aluMixData(ALCdevice *device, ALvoid *OutBuffer, const ALuint NumSamples)
*/
switch(device->FmtType)
{
-#define HANDLE_WRITE(T) case T: \
- Write<T>(RealOut, OutBuffer, SamplesDone, SamplesToDo); break;
- HANDLE_WRITE(DevFmtByte)
- HANDLE_WRITE(DevFmtUByte)
- HANDLE_WRITE(DevFmtShort)
- HANDLE_WRITE(DevFmtUShort)
- HANDLE_WRITE(DevFmtInt)
- HANDLE_WRITE(DevFmtUInt)
- HANDLE_WRITE(DevFmtFloat)
+#define HANDLE_WRITE(T) case T: \
+ Write<T>(RealOut, OutBuffer, SamplesDone, SamplesToDo, FrameStep); break;
+ HANDLE_WRITE(DevFmtByte)
+ HANDLE_WRITE(DevFmtUByte)
+ HANDLE_WRITE(DevFmtShort)
+ HANDLE_WRITE(DevFmtUShort)
+ HANDLE_WRITE(DevFmtInt)
+ HANDLE_WRITE(DevFmtUInt)
+ HANDLE_WRITE(DevFmtFloat)
#undef HANDLE_WRITE
}
}
diff --git a/alc/alu.h b/alc/alu.h
index b3cfd840..84a6d81b 100644
--- a/alc/alu.h
+++ b/alc/alu.h
@@ -148,7 +148,8 @@ inline std::array<ALfloat,MAX_AMBI_CHANNELS> GetAmbiIdentityRow(size_t i) noexce
}
-void aluMixData(ALCdevice *device, ALvoid *OutBuffer, const ALuint NumSamples);
+void aluMixData(ALCdevice *device, void *OutBuffer, const ALuint NumSamples,
+ const size_t FrameStep);
/* Caller must lock the device state, and the mixer must not be running. */
void aluHandleDisconnect(ALCdevice *device, const char *msg, ...) DECL_FORMAT(printf, 2, 3);
diff --git a/alc/backends/alsa.cpp b/alc/backends/alsa.cpp
index 7dc3c3c4..236e7a2f 100644
--- a/alc/backends/alsa.cpp
+++ b/alc/backends/alsa.cpp
@@ -446,6 +446,7 @@ int AlsaPlayback::mixerProc()
SetRTPriority();
althrd_setname(MIXER_THREAD_NAME);
+ const size_t samplebits{mDevice->bytesFromFmt() * 8};
const snd_pcm_uframes_t update_size{mDevice->UpdateSize};
const snd_pcm_uframes_t buffer_size{mDevice->BufferSize};
while(!mKillNow.load(std::memory_order_acquire))
@@ -507,7 +508,7 @@ int AlsaPlayback::mixerProc()
}
char *WritePtr{static_cast<char*>(areas->addr) + (offset * areas->step / 8)};
- aluMixData(mDevice, WritePtr, static_cast<ALuint>(frames));
+ aluMixData(mDevice, WritePtr, static_cast<ALuint>(frames), areas->step / samplebits);
snd_pcm_sframes_t commitres{snd_pcm_mmap_commit(mPcmHandle, offset, frames)};
if(commitres < 0 || (static_cast<snd_pcm_uframes_t>(commitres)-frames) != 0)
@@ -529,6 +530,7 @@ int AlsaPlayback::mixerNoMMapProc()
SetRTPriority();
althrd_setname(MIXER_THREAD_NAME);
+ const size_t frame_step{mDevice->channelsFromFmt()};
const snd_pcm_uframes_t update_size{mDevice->UpdateSize};
const snd_pcm_uframes_t buffer_size{mDevice->BufferSize};
while(!mKillNow.load(std::memory_order_acquire))
@@ -574,7 +576,7 @@ int AlsaPlayback::mixerNoMMapProc()
std::lock_guard<AlsaPlayback> _{*this};
al::byte *WritePtr{mBuffer.data()};
avail = snd_pcm_bytes_to_frames(mPcmHandle, static_cast<ssize_t>(mBuffer.size()));
- aluMixData(mDevice, WritePtr, static_cast<ALuint>(avail));
+ aluMixData(mDevice, WritePtr, static_cast<ALuint>(avail), frame_step);
while(avail > 0)
{
snd_pcm_sframes_t ret{snd_pcm_writei(mPcmHandle, WritePtr,
diff --git a/alc/backends/coreaudio.cpp b/alc/backends/coreaudio.cpp
index 7c18287b..a8527bed 100644
--- a/alc/backends/coreaudio.cpp
+++ b/alc/backends/coreaudio.cpp
@@ -82,7 +82,8 @@ OSStatus CoreAudioPlayback::MixerProc(AudioUnitRenderActionFlags*, const AudioTi
UInt32, AudioBufferList *ioData) noexcept
{
std::lock_guard<CoreAudioPlayback> _{*this};
- aluMixData(mDevice, ioData->mBuffers[0].mData, ioData->mBuffers[0].mDataByteSize/mFrameSize);
+ aluMixData(mDevice, ioData->mBuffers[0].mData, ioData->mBuffers[0].mDataByteSize/mFrameSize,
+ ioData->mBuffers[0].mNumberChannels);
return noErr;
}
diff --git a/alc/backends/dsound.cpp b/alc/backends/dsound.cpp
index c04ba9e4..69fb5fb0 100644
--- a/alc/backends/dsound.cpp
+++ b/alc/backends/dsound.cpp
@@ -219,6 +219,7 @@ FORCE_ALIGN int DSoundPlayback::mixerProc()
return 1;
}
+ const size_t FrameStep{mDevice->channelsFromFmt()};
ALuint FrameSize{mDevice->frameSizeFromFmt()};
DWORD FragSize{mDevice->UpdateSize * FrameSize};
@@ -276,9 +277,9 @@ FORCE_ALIGN int DSoundPlayback::mixerProc()
if(SUCCEEDED(err))
{
std::unique_lock<DSoundPlayback> dlock{*this};
- aluMixData(mDevice, WritePtr1, WriteCnt1/FrameSize);
+ aluMixData(mDevice, WritePtr1, WriteCnt1/FrameSize, FrameStep);
if(WriteCnt2 > 0)
- aluMixData(mDevice, WritePtr2, WriteCnt2/FrameSize);
+ aluMixData(mDevice, WritePtr2, WriteCnt2/FrameSize, FrameStep);
dlock.unlock();
mBuffer->Unlock(WritePtr1, WriteCnt1, WritePtr2, WriteCnt2);
diff --git a/alc/backends/jack.cpp b/alc/backends/jack.cpp
index c7bf8469..2be52e35 100644
--- a/alc/backends/jack.cpp
+++ b/alc/backends/jack.cpp
@@ -292,6 +292,8 @@ int JackPlayback::mixerProc()
SetRTPriority();
althrd_setname(MIXER_THREAD_NAME);
+ const size_t frame_step{mDevice->channelsFromFmt()};
+
std::unique_lock<JackPlayback> dlock{*this};
while(!mKillNow.load(std::memory_order_acquire) &&
mDevice->Connected.load(std::memory_order_acquire))
@@ -311,9 +313,9 @@ int JackPlayback::mixerProc()
ALuint len1{minu(static_cast<ALuint>(data.first.len), todo)};
ALuint len2{minu(static_cast<ALuint>(data.second.len), todo-len1)};
- aluMixData(mDevice, data.first.buf, len1);
+ aluMixData(mDevice, data.first.buf, len1, frame_step);
if(len2 > 0)
- aluMixData(mDevice, data.second.buf, len2);
+ aluMixData(mDevice, data.second.buf, len2, frame_step);
mRing->writeAdvance(todo);
}
diff --git a/alc/backends/null.cpp b/alc/backends/null.cpp
index bc2a0c9c..9f069be8 100644
--- a/alc/backends/null.cpp
+++ b/alc/backends/null.cpp
@@ -87,7 +87,7 @@ int NullBackend::mixerProc()
while(avail-done >= mDevice->UpdateSize)
{
std::lock_guard<NullBackend> _{*this};
- aluMixData(mDevice, nullptr, mDevice->UpdateSize);
+ aluMixData(mDevice, nullptr, mDevice->UpdateSize, 0u);
done += mDevice->UpdateSize;
}
diff --git a/alc/backends/opensl.cpp b/alc/backends/opensl.cpp
index a1fdccc7..ab2b8c2c 100644
--- a/alc/backends/opensl.cpp
+++ b/alc/backends/opensl.cpp
@@ -228,6 +228,8 @@ int OpenSLPlayback::mixerProc()
PRINTERR(result, "bufferQueue->GetInterface SL_IID_PLAY");
}
+ const size_t frame_step{mDevice->channelsFromFmt()};
+
std::unique_lock<OpenSLPlayback> dlock{*this};
if(SL_RESULT_SUCCESS != result)
aluHandleDisconnect(mDevice, "Failed to get playback buffer: 0x%08x", result);
@@ -263,10 +265,10 @@ int OpenSLPlayback::mixerProc()
auto data = mRing->getWriteVector();
aluMixData(mDevice, data.first.buf,
- static_cast<ALuint>(data.first.len*mDevice->UpdateSize));
+ static_cast<ALuint>(data.first.len*mDevice->UpdateSize), frame_step);
if(data.second.len > 0)
aluMixData(mDevice, data.second.buf,
- static_cast<ALuint>(data.second.len*mDevice->UpdateSize));
+ static_cast<ALuint>(data.second.len*mDevice->UpdateSize), frame_step);
size_t todo{data.first.len + data.second.len};
mRing->writeAdvance(todo);
diff --git a/alc/backends/oss.cpp b/alc/backends/oss.cpp
index 59cc44e4..b3f8936a 100644
--- a/alc/backends/oss.cpp
+++ b/alc/backends/oss.cpp
@@ -277,6 +277,7 @@ int OSSPlayback::mixerProc()
SetRTPriority();
althrd_setname(MIXER_THREAD_NAME);
+ const size_t frame_step{mDevice->channelsFromFmt()};
const ALuint frame_size{mDevice->frameSizeFromFmt()};
std::unique_lock<OSSPlayback> dlock{*this};
@@ -306,7 +307,7 @@ int OSSPlayback::mixerProc()
ALubyte *write_ptr{mMixData.data()};
size_t to_write{mMixData.size()};
- aluMixData(mDevice, write_ptr, static_cast<ALuint>(to_write/frame_size));
+ aluMixData(mDevice, write_ptr, static_cast<ALuint>(to_write/frame_size), frame_step);
while(to_write > 0 && !mKillNow.load(std::memory_order_acquire))
{
ssize_t wrote{write(mFd, write_ptr, to_write)};
diff --git a/alc/backends/portaudio.cpp b/alc/backends/portaudio.cpp
index 1e3d0ce8..5de9ab58 100644
--- a/alc/backends/portaudio.cpp
+++ b/alc/backends/portaudio.cpp
@@ -110,7 +110,8 @@ int PortPlayback::writeCallback(const void*, void *outputBuffer, unsigned long f
const PaStreamCallbackTimeInfo*, const PaStreamCallbackFlags) noexcept
{
std::lock_guard<PortPlayback> _{*this};
- aluMixData(mDevice, outputBuffer, static_cast<ALuint>(framesPerBuffer));
+ aluMixData(mDevice, outputBuffer, static_cast<ALuint>(framesPerBuffer),
+ mDevice->channelsFromFmt());
return 0;
}
diff --git a/alc/backends/pulseaudio.cpp b/alc/backends/pulseaudio.cpp
index 4e46460b..be4e742c 100644
--- a/alc/backends/pulseaudio.cpp
+++ b/alc/backends/pulseaudio.cpp
@@ -763,7 +763,7 @@ void PulsePlayback::streamStateCallback(pa_stream *stream) noexcept
void PulsePlayback::streamWriteCallback(pa_stream *stream, size_t nbytes) noexcept
{
void *buf{pa_xmalloc(nbytes)};
- aluMixData(mDevice, buf, static_cast<ALuint>(nbytes/mFrameSize));
+ aluMixData(mDevice, buf, static_cast<ALuint>(nbytes/mFrameSize), mDevice->channelsFromFmt());
int ret{pa_stream_write(stream, buf, nbytes, pa_xfree, 0, PA_SEEK_RELATIVE)};
if UNLIKELY(ret != PA_OK)
diff --git a/alc/backends/sdl2.cpp b/alc/backends/sdl2.cpp
index 25b5d4d9..abb240e4 100644
--- a/alc/backends/sdl2.cpp
+++ b/alc/backends/sdl2.cpp
@@ -85,7 +85,7 @@ void Sdl2Backend::audioCallback(Uint8 *stream, int len) noexcept
{
const auto ulen = static_cast<unsigned int>(len);
assert((ulen % mFrameSize) == 0);
- aluMixData(mDevice, stream, ulen / mFrameSize);
+ aluMixData(mDevice, stream, ulen / mFrameSize, mDevice->channelsFromFmt());
}
void Sdl2Backend::open(const ALCchar *name)
diff --git a/alc/backends/sndio.cpp b/alc/backends/sndio.cpp
index 7799316f..4d851391 100644
--- a/alc/backends/sndio.cpp
+++ b/alc/backends/sndio.cpp
@@ -77,6 +77,7 @@ int SndioPlayback::mixerProc()
SetRTPriority();
althrd_setname(MIXER_THREAD_NAME);
+ const size_t frameStep{mDevice->channelsFromFmt()};
const ALuint frameSize{mDevice->frameSizeFromFmt()};
while(!mKillNow.load(std::memory_order_acquire) &&
@@ -87,7 +88,7 @@ int SndioPlayback::mixerProc()
{
std::lock_guard<SndioPlayback> _{*this};
- aluMixData(mDevice, WritePtr, static_cast<ALuint>(len/frameSize));
+ aluMixData(mDevice, WritePtr, static_cast<ALuint>(len/frameSize), frameStep);
}
while(len > 0 && !mKillNow.load(std::memory_order_acquire))
{
diff --git a/alc/backends/solaris.cpp b/alc/backends/solaris.cpp
index 7cc2606e..6823777c 100644
--- a/alc/backends/solaris.cpp
+++ b/alc/backends/solaris.cpp
@@ -89,6 +89,7 @@ int SolarisBackend::mixerProc()
SetRTPriority();
althrd_setname(MIXER_THREAD_NAME);
+ const size_t frame_step{mDevice->channelsFromFmt()};
const ALuint frame_size{mDevice->frameSizeFromFmt()};
std::unique_lock<SolarisBackend> dlock{*this};
@@ -119,7 +120,7 @@ int SolarisBackend::mixerProc()
ALubyte *write_ptr{mBuffer.data()};
size_t to_write{mBuffer.size()};
- aluMixData(mDevice, write_ptr, to_write/frame_size);
+ aluMixData(mDevice, write_ptr, to_write/frame_size, frame_step);
while(to_write > 0 && !mKillNow.load(std::memory_order_acquire))
{
ssize_t wrote{write(mFd, write_ptr, to_write)};
diff --git a/alc/backends/wasapi.cpp b/alc/backends/wasapi.cpp
index 37a547af..900e204f 100644
--- a/alc/backends/wasapi.cpp
+++ b/alc/backends/wasapi.cpp
@@ -106,6 +106,19 @@ inline int64_t ScaleCeil(int64_t val, int64_t new_scale, int64_t old_scale)
}
+class GuidPrinter {
+ char mMsg[64];
+
+public:
+ GuidPrinter(const GUID &guid)
+ {
+ std::snprintf(mMsg, al::size(mMsg), "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
+ DWORD{guid.Data1}, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2],
+ guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
+ }
+ const char *c_str() const { return mMsg; }
+};
+
struct PropVariant {
PROPVARIANT mProp;
@@ -356,21 +369,6 @@ void TraceFormat(const char *msg, const WAVEFORMATEX *format)
constexpr size_t fmtex_extra_size{sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX)};
if(format->wFormatTag == WAVE_FORMAT_EXTENSIBLE && format->cbSize >= fmtex_extra_size)
{
- class GuidPrinter {
- char mMsg[64];
-
- public:
- GuidPrinter(const GUID &guid)
- {
- std::snprintf(mMsg, al::size(mMsg),
- "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
- DWORD{guid.Data1}, guid.Data2, guid.Data3,
- guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
- guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
- }
- const char *c_str() const { return mMsg; }
- };
-
const WAVEFORMATEXTENSIBLE *fmtex{
CONTAINING_RECORD(format, const WAVEFORMATEXTENSIBLE, Format)};
TRACE("%s:\n"
@@ -452,7 +450,8 @@ struct WasapiProxy {
{
std::promise<HRESULT> promise;
std::future<HRESULT> future{promise.get_future()};
- { std::lock_guard<std::mutex> _{mMsgQueueLock};
+ {
+ std::lock_guard<std::mutex> _{mMsgQueueLock};
mMsgQueue.emplace_back(Msg{type, this, std::move(promise)});
}
mMsgQueueCond.notify_one();
@@ -463,7 +462,8 @@ struct WasapiProxy {
{
std::promise<HRESULT> promise;
std::future<HRESULT> future{promise.get_future()};
- { std::lock_guard<std::mutex> _{mMsgQueueLock};
+ {
+ std::lock_guard<std::mutex> _{mMsgQueueLock};
mMsgQueue.emplace_back(Msg{type, nullptr, std::move(promise)});
}
mMsgQueueCond.notify_one();
@@ -631,6 +631,7 @@ struct WasapiPlayback final : public BackendBase, WasapiProxy {
IAudioRenderClient *mRender{nullptr};
HANDLE mNotifyEvent{nullptr};
+ UINT32 mFrameStep{0u};
std::atomic<UINT32> mPadding{0u};
std::atomic<bool> mKillNow{true};
@@ -690,7 +691,7 @@ FORCE_ALIGN int WasapiPlayback::mixerProc()
if(SUCCEEDED(hr))
{
std::unique_lock<WasapiPlayback> dlock{*this};
- aluMixData(mDevice, buffer, len);
+ aluMixData(mDevice, buffer, len, mFrameStep);
mPadding.store(written + len, std::memory_order_relaxed);
dlock.unlock();
hr = mRender->ReleaseBuffer(len, 0);
@@ -988,6 +989,11 @@ HRESULT WasapiPlayback::resetProxy()
mDevice->FmtChans = DevFmtX61;
else if(OutputType.Format.nChannels == 8 && (OutputType.dwChannelMask == X7DOT1 || OutputType.dwChannelMask == X7DOT1_WIDE))
mDevice->FmtChans = DevFmtX71;
+ else if(OutputType.Format.nChannels >= 2 && (OutputType.dwChannelMask&STEREO) == STEREO)
+ {
+ TRACE("Mixing stereo over channels: %d -- 0x%08lx\n", OutputType.Format.nChannels, OutputType.dwChannelMask);
+ mDevice->FmtChans = DevFmtStereo;
+ }
else
{
ERR("Unhandled extensible channels: %d -- 0x%08lx\n", OutputType.Format.nChannels, OutputType.dwChannelMask);
@@ -1026,6 +1032,7 @@ HRESULT WasapiPlayback::resetProxy()
}
OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample;
}
+ mFrameStep = OutputType.Format.nChannels;
EndpointFormFactor formfactor = UnknownFormFactor;
get_device_formfactor(mMMDev, &formfactor);
diff --git a/alc/backends/wave.cpp b/alc/backends/wave.cpp
index 7bcc3436..4f357970 100644
--- a/alc/backends/wave.cpp
+++ b/alc/backends/wave.cpp
@@ -126,6 +126,7 @@ int WaveBackend::mixerProc()
althrd_setname(MIXER_THREAD_NAME);
+ const size_t frameStep{mDevice->channelsFromFmt()};
const ALuint frameSize{mDevice->frameSizeFromFmt()};
int64_t done{0};
@@ -147,7 +148,7 @@ int WaveBackend::mixerProc()
{
{
std::lock_guard<WaveBackend> _{*this};
- aluMixData(mDevice, mBuffer.data(), mDevice->UpdateSize);
+ aluMixData(mDevice, mBuffer.data(), mDevice->UpdateSize, frameStep);
}
done += mDevice->UpdateSize;
diff --git a/alc/backends/winmm.cpp b/alc/backends/winmm.cpp
index 649bb345..82625e1f 100644
--- a/alc/backends/winmm.cpp
+++ b/alc/backends/winmm.cpp
@@ -180,6 +180,8 @@ FORCE_ALIGN int WinMMPlayback::mixerProc()
SetRTPriority();
althrd_setname(MIXER_THREAD_NAME);
+ const size_t frame_step{mDevice->channelsFromFmt()};
+
std::unique_lock<WinMMPlayback> dlock{*this};
while(!mKillNow.load(std::memory_order_acquire) &&
mDevice->Connected.load(std::memory_order_acquire))
@@ -198,7 +200,7 @@ FORCE_ALIGN int WinMMPlayback::mixerProc()
WAVEHDR &waveHdr = mWaveBuffer[widx];
widx = (widx+1) % mWaveBuffer.size();
- aluMixData(mDevice, waveHdr.lpData, mDevice->UpdateSize);
+ aluMixData(mDevice, waveHdr.lpData, mDevice->UpdateSize, frame_step);
mWritable.fetch_sub(1, std::memory_order_acq_rel);
waveOutWrite(mOutHdl, &waveHdr, sizeof(WAVEHDR));
} while(--todo);