aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);