diff options
-rw-r--r-- | alc/alc.cpp | 2 | ||||
-rw-r--r-- | alc/alu.cpp | 34 | ||||
-rw-r--r-- | alc/alu.h | 3 | ||||
-rw-r--r-- | alc/backends/alsa.cpp | 6 | ||||
-rw-r--r-- | alc/backends/coreaudio.cpp | 3 | ||||
-rw-r--r-- | alc/backends/dsound.cpp | 5 | ||||
-rw-r--r-- | alc/backends/jack.cpp | 6 | ||||
-rw-r--r-- | alc/backends/null.cpp | 2 | ||||
-rw-r--r-- | alc/backends/opensl.cpp | 6 | ||||
-rw-r--r-- | alc/backends/oss.cpp | 3 | ||||
-rw-r--r-- | alc/backends/portaudio.cpp | 3 | ||||
-rw-r--r-- | alc/backends/pulseaudio.cpp | 2 | ||||
-rw-r--r-- | alc/backends/sdl2.cpp | 2 | ||||
-rw-r--r-- | alc/backends/sndio.cpp | 3 | ||||
-rw-r--r-- | alc/backends/solaris.cpp | 3 | ||||
-rw-r--r-- | alc/backends/wasapi.cpp | 43 | ||||
-rw-r--r-- | alc/backends/wave.cpp | 3 | ||||
-rw-r--r-- | alc/backends/winmm.cpp | 4 |
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 } } @@ -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); |