From cb3e96e75640730b9391f0d2d922eecd9ee2ce79 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 28 Jul 2019 18:56:04 -0700 Subject: Rename Alc to alc --- alc/ringbuffer.cpp | 253 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 alc/ringbuffer.cpp (limited to 'alc/ringbuffer.cpp') diff --git a/alc/ringbuffer.cpp b/alc/ringbuffer.cpp new file mode 100644 index 00000000..6ef576a5 --- /dev/null +++ b/alc/ringbuffer.cpp @@ -0,0 +1,253 @@ +/** + * OpenAL cross platform audio library + * Copyright (C) 1999-2007 by authors. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * Or go to http://www.gnu.org/copyleft/lgpl.html + */ + +#include "config.h" + +#include +#include +#include + +#include + +#include "ringbuffer.h" +#include "atomic.h" +#include "threads.h" +#include "almalloc.h" +#include "compat.h" + + +RingBufferPtr CreateRingBuffer(size_t sz, size_t elem_sz, int limit_writes) +{ + size_t power_of_two{0u}; + if(sz > 0) + { + power_of_two = sz; + power_of_two |= power_of_two>>1; + power_of_two |= power_of_two>>2; + power_of_two |= power_of_two>>4; + power_of_two |= power_of_two>>8; + power_of_two |= power_of_two>>16; +#if SIZE_MAX > UINT_MAX + power_of_two |= power_of_two>>32; +#endif + } + ++power_of_two; + if(power_of_two < sz) return nullptr; + + const size_t bufbytes{power_of_two * elem_sz}; + RingBufferPtr rb{new (al_calloc(16, sizeof(*rb) + bufbytes)) RingBuffer{bufbytes}}; + rb->mWriteSize = limit_writes ? sz : (power_of_two-1); + rb->mSizeMask = power_of_two - 1; + rb->mElemSize = elem_sz; + + return rb; +} + +void RingBuffer::reset() noexcept +{ + mWritePtr.store(0, std::memory_order_relaxed); + mReadPtr.store(0, std::memory_order_relaxed); + std::fill_n(mBuffer.begin(), (mSizeMask+1)*mElemSize, al::byte{}); +} + + +size_t RingBuffer::readSpace() const noexcept +{ + size_t w = mWritePtr.load(std::memory_order_acquire); + size_t r = mReadPtr.load(std::memory_order_acquire); + return (w-r) & mSizeMask; +} + +size_t RingBuffer::writeSpace() const noexcept +{ + size_t w = mWritePtr.load(std::memory_order_acquire); + size_t r = mReadPtr.load(std::memory_order_acquire) + mWriteSize - mSizeMask; + return (r-w-1) & mSizeMask; +} + + +size_t RingBuffer::read(void *dest, size_t cnt) noexcept +{ + const size_t free_cnt{readSpace()}; + if(free_cnt == 0) return 0; + + const size_t to_read{std::min(cnt, free_cnt)}; + size_t read_ptr{mReadPtr.load(std::memory_order_relaxed) & mSizeMask}; + + size_t n1, n2; + const size_t cnt2{read_ptr + to_read}; + if(cnt2 > mSizeMask+1) + { + n1 = mSizeMask+1 - read_ptr; + n2 = cnt2 & mSizeMask; + } + else + { + n1 = to_read; + n2 = 0; + } + + auto outiter = std::copy_n(mBuffer.begin() + read_ptr*mElemSize, n1*mElemSize, + static_cast(dest)); + read_ptr += n1; + if(n2 > 0) + { + std::copy_n(mBuffer.begin(), n2*mElemSize, outiter); + read_ptr += n2; + } + mReadPtr.store(read_ptr, std::memory_order_release); + return to_read; +} + +size_t RingBuffer::peek(void *dest, size_t cnt) const noexcept +{ + const size_t free_cnt{readSpace()}; + if(free_cnt == 0) return 0; + + const size_t to_read{std::min(cnt, free_cnt)}; + size_t read_ptr{mReadPtr.load(std::memory_order_relaxed) & mSizeMask}; + + size_t n1, n2; + const size_t cnt2{read_ptr + to_read}; + if(cnt2 > mSizeMask+1) + { + n1 = mSizeMask+1 - read_ptr; + n2 = cnt2 & mSizeMask; + } + else + { + n1 = to_read; + n2 = 0; + } + + auto outiter = std::copy_n(mBuffer.begin() + read_ptr*mElemSize, n1*mElemSize, + static_cast(dest)); + if(n2 > 0) + std::copy_n(mBuffer.begin(), n2*mElemSize, outiter); + return to_read; +} + +size_t RingBuffer::write(const void *src, size_t cnt) noexcept +{ + const size_t free_cnt{writeSpace()}; + if(free_cnt == 0) return 0; + + const size_t to_write{std::min(cnt, free_cnt)}; + size_t write_ptr{mWritePtr.load(std::memory_order_relaxed) & mSizeMask}; + + size_t n1, n2; + const size_t cnt2{write_ptr + to_write}; + if(cnt2 > mSizeMask+1) + { + n1 = mSizeMask+1 - write_ptr; + n2 = cnt2 & mSizeMask; + } + else + { + n1 = to_write; + n2 = 0; + } + + auto srcbytes = static_cast(src); + std::copy_n(srcbytes, n1*mElemSize, mBuffer.begin() + write_ptr*mElemSize); + write_ptr += n1; + if(n2 > 0) + { + std::copy_n(srcbytes + n1*mElemSize, n2*mElemSize, mBuffer.begin()); + write_ptr += n2; + } + mWritePtr.store(write_ptr, std::memory_order_release); + return to_write; +} + + +void RingBuffer::readAdvance(size_t cnt) noexcept +{ + mReadPtr.fetch_add(cnt, std::memory_order_acq_rel); +} + +void RingBuffer::writeAdvance(size_t cnt) noexcept +{ + mWritePtr.fetch_add(cnt, std::memory_order_acq_rel); +} + + +ll_ringbuffer_data_pair RingBuffer::getReadVector() const noexcept +{ + ll_ringbuffer_data_pair ret; + + size_t w{mWritePtr.load(std::memory_order_acquire)}; + size_t r{mReadPtr.load(std::memory_order_acquire)}; + w &= mSizeMask; + r &= mSizeMask; + const size_t free_cnt{(w-r) & mSizeMask}; + + const size_t cnt2{r + free_cnt}; + if(cnt2 > mSizeMask+1) + { + /* Two part vector: the rest of the buffer after the current read ptr, + * plus some from the start of the buffer. */ + ret.first.buf = const_cast(mBuffer.data() + r*mElemSize); + ret.first.len = mSizeMask+1 - r; + ret.second.buf = const_cast(mBuffer.data()); + ret.second.len = cnt2 & mSizeMask; + } + else + { + /* Single part vector: just the rest of the buffer */ + ret.first.buf = const_cast(mBuffer.data() + r*mElemSize); + ret.first.len = free_cnt; + ret.second.buf = nullptr; + ret.second.len = 0; + } + + return ret; +} + +ll_ringbuffer_data_pair RingBuffer::getWriteVector() const noexcept +{ + ll_ringbuffer_data_pair ret; + + size_t w{mWritePtr.load(std::memory_order_acquire)}; + size_t r{mReadPtr.load(std::memory_order_acquire) + mWriteSize - mSizeMask}; + w &= mSizeMask; + r &= mSizeMask; + const size_t free_cnt{(r-w-1) & mSizeMask}; + + const size_t cnt2{w + free_cnt}; + if(cnt2 > mSizeMask+1) + { + /* Two part vector: the rest of the buffer after the current write ptr, + * plus some from the start of the buffer. */ + ret.first.buf = const_cast(mBuffer.data() + w*mElemSize); + ret.first.len = mSizeMask+1 - w; + ret.second.buf = const_cast(mBuffer.data()); + ret.second.len = cnt2 & mSizeMask; + } + else + { + ret.first.buf = const_cast(mBuffer.data() + w*mElemSize); + ret.first.len = free_cnt; + ret.second.buf = nullptr; + ret.second.len = 0; + } + + return ret; +} -- cgit v1.2.3 From d38d2553649555714bfe20f8ca72614974993d47 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 28 Jul 2019 21:29:59 -0700 Subject: More include cleanups --- OpenAL32/alAuxEffectSlot.cpp | 24 +++++++++++++++--------- OpenAL32/alAuxEffectSlot.h | 19 +++++++++++-------- OpenAL32/alBuffer.cpp | 5 ++--- OpenAL32/alBuffer.h | 13 +++++++------ OpenAL32/alEffect.cpp | 2 +- OpenAL32/alEffect.h | 8 +++++--- OpenAL32/alError.cpp | 10 +++++----- OpenAL32/alError.h | 8 +++++--- OpenAL32/alExtension.cpp | 7 ++++--- OpenAL32/alFilter.cpp | 17 +++++++++++++---- OpenAL32/alFilter.h | 6 +++--- OpenAL32/alListener.cpp | 15 ++++++++++----- OpenAL32/alListener.h | 9 ++++----- OpenAL32/alSource.cpp | 3 --- OpenAL32/alSource.h | 22 +++++++++++++--------- alc/alu.h | 4 ++-- alc/converter.cpp | 3 +++ alc/converter.h | 7 ++++++- alc/hrtf.h | 2 +- alc/mastering.cpp | 16 +++++++++++----- alc/mastering.h | 4 ++-- alc/ringbuffer.cpp | 10 +++------- alc/uhjfilter.cpp | 5 ++++- 23 files changed, 130 insertions(+), 89 deletions(-) (limited to 'alc/ringbuffer.cpp') diff --git a/OpenAL32/alAuxEffectSlot.cpp b/OpenAL32/alAuxEffectSlot.cpp index cc2893c3..42966bf2 100644 --- a/OpenAL32/alAuxEffectSlot.cpp +++ b/OpenAL32/alAuxEffectSlot.cpp @@ -20,25 +20,31 @@ #include "config.h" -#include -#include +#include "alAuxEffectSlot.h" -#include #include +#include +#include +#include +#include +#include #include "AL/al.h" #include "AL/alc.h" +#include "alEffect.h" +#include "alError.h" #include "alcmain.h" #include "alcontext.h" -#include "alAuxEffectSlot.h" -#include "alError.h" -#include "alListener.h" -#include "alSource.h" - -#include "fpu_modes.h" #include "alexcpt.h" #include "almalloc.h" +#include "alnumeric.h" +#include "alspan.h" +#include "alu.h" +#include "fpu_modes.h" +#include "inprogext.h" +#include "logging.h" +#include "opthelpers.h" namespace { diff --git a/OpenAL32/alAuxEffectSlot.h b/OpenAL32/alAuxEffectSlot.h index b6976d13..369638a0 100644 --- a/OpenAL32/alAuxEffectSlot.h +++ b/OpenAL32/alAuxEffectSlot.h @@ -1,17 +1,20 @@ -#ifndef _AL_AUXEFFECTSLOT_H_ -#define _AL_AUXEFFECTSLOT_H_ +#ifndef AL_AUXEFFECTSLOT_H +#define AL_AUXEFFECTSLOT_H -#include +#include +#include -#include "alcmain.h" -#include "alEffect.h" -#include "ambidefs.h" -#include "effects/base.h" +#include "AL/al.h" +#include "AL/alc.h" +#include "AL/efx.h" +#include "alcmain.h" #include "almalloc.h" #include "atomic.h" +#include "effects/base.h" +#include "vector.h" - +struct ALeffect; struct ALeffectslot; diff --git a/OpenAL32/alBuffer.cpp b/OpenAL32/alBuffer.cpp index 597f98cb..505b9dab 100644 --- a/OpenAL32/alBuffer.cpp +++ b/OpenAL32/alBuffer.cpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include @@ -40,9 +40,9 @@ #include "AL/alc.h" #include "AL/alext.h" -#include "alcmain.h" #include "alError.h" #include "albyte.h" +#include "alcmain.h" #include "alcontext.h" #include "alexcpt.h" #include "almalloc.h" @@ -51,7 +51,6 @@ #include "atomic.h" #include "inprogext.h" #include "opthelpers.h" -#include "vector.h" namespace { diff --git a/OpenAL32/alBuffer.h b/OpenAL32/alBuffer.h index 92655784..1d5873e5 100644 --- a/OpenAL32/alBuffer.h +++ b/OpenAL32/alBuffer.h @@ -1,14 +1,15 @@ -#ifndef _AL_BUFFER_H_ -#define _AL_BUFFER_H_ +#ifndef AL_BUFFER_H +#define AL_BUFFER_H + +#include -#include "AL/alc.h" #include "AL/al.h" -#include "AL/alext.h" -#include "inprogext.h" +#include "albyte.h" +#include "almalloc.h" #include "atomic.h" +#include "inprogext.h" #include "vector.h" -#include "albyte.h" /* User formats */ diff --git a/OpenAL32/alEffect.cpp b/OpenAL32/alEffect.cpp index 14353d1c..4a75f69f 100644 --- a/OpenAL32/alEffect.cpp +++ b/OpenAL32/alEffect.cpp @@ -37,8 +37,8 @@ #include "AL/efx-presets.h" #include "AL/efx.h" -#include "alcmain.h" #include "alError.h" +#include "alcmain.h" #include "alcontext.h" #include "alexcpt.h" #include "almalloc.h" diff --git a/OpenAL32/alEffect.h b/OpenAL32/alEffect.h index d43aa206..270b8e20 100644 --- a/OpenAL32/alEffect.h +++ b/OpenAL32/alEffect.h @@ -1,7 +1,9 @@ -#ifndef _AL_EFFECT_H_ -#define _AL_EFFECT_H_ +#ifndef AL_EFFECT_H +#define AL_EFFECT_H + +#include "AL/al.h" +#include "AL/efx.h" -#include "alcmain.h" #include "effects/base.h" diff --git a/OpenAL32/alError.cpp b/OpenAL32/alError.cpp index 782e10ec..159aee52 100644 --- a/OpenAL32/alError.cpp +++ b/OpenAL32/alError.cpp @@ -22,6 +22,11 @@ #include "alError.h" +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#endif + #include #include #include @@ -29,11 +34,6 @@ #include #include -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#endif - #include "AL/al.h" #include "AL/alc.h" diff --git a/OpenAL32/alError.h b/OpenAL32/alError.h index 0abd6b26..6408b60c 100644 --- a/OpenAL32/alError.h +++ b/OpenAL32/alError.h @@ -1,7 +1,9 @@ -#ifndef _AL_ERROR_H_ -#define _AL_ERROR_H_ +#ifndef AL_ERROR_H +#define AL_ERROR_H + +#include "AL/al.h" +#include "AL/alc.h" -#include "alcmain.h" #include "logging.h" diff --git a/OpenAL32/alExtension.cpp b/OpenAL32/alExtension.cpp index 5abcf1cf..80681090 100644 --- a/OpenAL32/alExtension.cpp +++ b/OpenAL32/alExtension.cpp @@ -20,17 +20,18 @@ #include "config.h" +#include #include #include -#include #include "AL/al.h" #include "AL/alc.h" -#include "alcmain.h" -#include "alcontext.h" #include "alError.h" +#include "alcontext.h" #include "alexcpt.h" +#include "opthelpers.h" + AL_API ALboolean AL_APIENTRY alIsExtensionPresent(const ALchar *extName) START_API_FUNC diff --git a/OpenAL32/alFilter.cpp b/OpenAL32/alFilter.cpp index cac12581..31fbaf21 100644 --- a/OpenAL32/alFilter.cpp +++ b/OpenAL32/alFilter.cpp @@ -20,16 +20,25 @@ #include "config.h" -#include +#include "alFilter.h" #include +#include +#include +#include +#include +#include + +#include "AL/efx.h" +#include "alError.h" #include "alcmain.h" #include "alcontext.h" -#include "alu.h" -#include "alFilter.h" -#include "alError.h" #include "alexcpt.h" +#include "almalloc.h" +#include "alnumeric.h" +#include "opthelpers.h" +#include "vector.h" namespace { diff --git a/OpenAL32/alFilter.h b/OpenAL32/alFilter.h index 1c033ac3..db098d70 100644 --- a/OpenAL32/alFilter.h +++ b/OpenAL32/alFilter.h @@ -1,8 +1,8 @@ -#ifndef _AL_FILTER_H_ -#define _AL_FILTER_H_ +#ifndef AL_FILTER_H +#define AL_FILTER_H -#include "AL/alc.h" #include "AL/al.h" +#include "AL/alc.h" #define LOWPASSFREQREF (5000.0f) diff --git a/OpenAL32/alListener.cpp b/OpenAL32/alListener.cpp index 067c0f55..d3bf3aaa 100644 --- a/OpenAL32/alListener.cpp +++ b/OpenAL32/alListener.cpp @@ -20,15 +20,20 @@ #include "config.h" +#include "alListener.h" + #include +#include + +#include "AL/efx.h" -#include "alcmain.h" -#include "alcontext.h" -#include "alu.h" #include "alError.h" -#include "alListener.h" -#include "alSource.h" +#include "alcontext.h" #include "alexcpt.h" +#include "almalloc.h" +#include "atomic.h" +#include "opthelpers.h" + #define DO_UPDATEPROPS() do { \ if(!context->DeferUpdates.load(std::memory_order_acquire)) \ diff --git a/OpenAL32/alListener.h b/OpenAL32/alListener.h index 4d59dbf9..a71db9f8 100644 --- a/OpenAL32/alListener.h +++ b/OpenAL32/alListener.h @@ -1,13 +1,12 @@ -#ifndef _AL_LISTENER_H_ -#define _AL_LISTENER_H_ +#ifndef AL_LISTENER_H +#define AL_LISTENER_H #include +#include -#include "AL/alc.h" #include "AL/al.h" -#include "AL/alext.h" +#include "AL/alc.h" -#include "atomic.h" #include "vecmat.h" enum class DistanceModel; diff --git a/OpenAL32/alSource.cpp b/OpenAL32/alSource.cpp index b080f874..4af5cc47 100644 --- a/OpenAL32/alSource.cpp +++ b/OpenAL32/alSource.cpp @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -39,7 +38,6 @@ #include #include #include -#include #include #include "AL/al.h" @@ -69,7 +67,6 @@ #include "opthelpers.h" #include "ringbuffer.h" #include "threads.h" -#include "vector.h" namespace { diff --git a/OpenAL32/alSource.h b/OpenAL32/alSource.h index 330bb9f4..c9892398 100644 --- a/OpenAL32/alSource.h +++ b/OpenAL32/alSource.h @@ -1,21 +1,25 @@ -#ifndef _AL_SOURCE_H_ -#define _AL_SOURCE_H_ +#ifndef AL_SOURCE_H +#define AL_SOURCE_H #include +#include +#include -#include "alcmain.h" -#include "alu.h" -#include "hrtf.h" -#include "almalloc.h" -#include "atomic.h" +#include "AL/al.h" +#include "AL/alc.h" -#define DEFAULT_SENDS 2 +#include "alcontext.h" +#include "alnumeric.h" +#include "alu.h" +#include "vector.h" struct ALbuffer; -struct ALsource; struct ALeffectslot; +#define DEFAULT_SENDS 2 + + struct ALbufferlistitem { std::atomic next; ALsizei max_samples; diff --git a/alc/alu.h b/alc/alu.h index 9acf904a..ef88bdf6 100644 --- a/alc/alu.h +++ b/alc/alu.h @@ -1,5 +1,5 @@ -#ifndef _ALU_H_ -#define _ALU_H_ +#ifndef ALU_H +#define ALU_H #include #include diff --git a/alc/converter.cpp b/alc/converter.cpp index 0f8e8941..2e357fb8 100644 --- a/alc/converter.cpp +++ b/alc/converter.cpp @@ -4,7 +4,10 @@ #include "converter.h" #include +#include +#include +#include "albyte.h" #include "fpu_modes.h" #include "mixer/defs.h" diff --git a/alc/converter.h b/alc/converter.h index 033e4d3f..bc51e46a 100644 --- a/alc/converter.h +++ b/alc/converter.h @@ -1,11 +1,16 @@ #ifndef CONVERTER_H #define CONVERTER_H +#include #include +#include "AL/al.h" + #include "alcmain.h" -#include "alu.h" #include "almalloc.h" +#include "alnumeric.h" +#include "alu.h" + struct SampleConverter { DevFmtType mSrcType{}; diff --git a/alc/hrtf.h b/alc/hrtf.h index 6c41cb82..29f7fce0 100644 --- a/alc/hrtf.h +++ b/alc/hrtf.h @@ -13,9 +13,9 @@ #include "atomic.h" #include "vector.h" - struct HrtfHandle; + #define HRTF_HISTORY_BITS (6) #define HRTF_HISTORY_LENGTH (1< -#include +#include "mastering.h" + #include +#include +#include #include +#include +#include +#include -#include "mastering.h" -#include "alu.h" #include "almalloc.h" -#include "math_defs.h" +#include "alnumeric.h" +#include "alu.h" +#include "opthelpers.h" /* These structures assume BUFFERSIZE is a power of 2. */ diff --git a/alc/mastering.h b/alc/mastering.h index 34dc8dcb..5be769ac 100644 --- a/alc/mastering.h +++ b/alc/mastering.h @@ -5,13 +5,13 @@ #include "AL/al.h" -#include "almalloc.h" /* For FloatBufferLine/BUFFERSIZE. */ #include "alcmain.h" - +#include "almalloc.h" struct SlidingHold; + /* General topology and basic automation was based on the following paper: * * D. Giannoulis, M. Massberg and J. D. Reiss, diff --git a/alc/ringbuffer.cpp b/alc/ringbuffer.cpp index 6ef576a5..d99676b8 100644 --- a/alc/ringbuffer.cpp +++ b/alc/ringbuffer.cpp @@ -20,17 +20,13 @@ #include "config.h" -#include -#include -#include +#include "ringbuffer.h" #include +#include +#include -#include "ringbuffer.h" -#include "atomic.h" -#include "threads.h" #include "almalloc.h" -#include "compat.h" RingBufferPtr CreateRingBuffer(size_t sz, size_t elem_sz, int limit_writes) diff --git a/alc/uhjfilter.cpp b/alc/uhjfilter.cpp index 55999647..b2cdf328 100644 --- a/alc/uhjfilter.cpp +++ b/alc/uhjfilter.cpp @@ -4,8 +4,11 @@ #include "uhjfilter.h" #include +#include + +#include "alnumeric.h" +#include "opthelpers.h" -#include "alu.h" namespace { -- cgit v1.2.3 From 5b37e2339bc91de3424b51600c3d3b96401d0b9c Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 11 Sep 2019 03:59:53 -0700 Subject: Simplify flexible array member usage --- alc/converter.cpp | 11 +++++------ alc/converter.h | 8 +------- alc/hrtf.cpp | 19 ++++--------------- alc/hrtf.h | 4 +--- alc/ringbuffer.cpp | 2 +- alc/ringbuffer.h | 4 +--- common/almalloc.h | 20 ++++++++++++++++++-- 7 files changed, 31 insertions(+), 37 deletions(-) (limited to 'alc/ringbuffer.cpp') diff --git a/alc/converter.cpp b/alc/converter.cpp index 7e3c17cc..58b59179 100644 --- a/alc/converter.cpp +++ b/alc/converter.cpp @@ -143,14 +143,13 @@ void Stereo2Mono(ALfloat *RESTRICT dst, const void *src, const size_t frames) no } // namespace -SampleConverterPtr CreateSampleConverter(DevFmtType srcType, DevFmtType dstType, ALsizei numchans, - ALsizei srcRate, ALsizei dstRate, Resampler resampler) +SampleConverterPtr CreateSampleConverter(DevFmtType srcType, DevFmtType dstType, size_t numchans, + ALsizei srcRate, ALsizei dstRate, Resampler resampler) { - if(numchans <= 0 || srcRate <= 0 || dstRate <= 0) + if(numchans < 1 || srcRate < 1 || dstRate < 1) return nullptr; - void *ptr{al_calloc(16, SampleConverter::Sizeof(numchans))}; - SampleConverterPtr converter{new (ptr) SampleConverter{static_cast(numchans)}}; + SampleConverterPtr converter{new (FamCount{numchans}) SampleConverter{numchans}}; converter->mSrcType = srcType; converter->mDstType = dstType; converter->mSrcTypeSize = BytesFromDevFmt(srcType); @@ -162,7 +161,7 @@ SampleConverterPtr CreateSampleConverter(DevFmtType srcType, DevFmtType dstType, /* Have to set the mixer FPU mode since that's what the resampler code expects. */ FPUCtl mixer_mode{}; auto step = static_cast( - mind(static_cast(srcRate)/dstRate*FRACTIONONE + 0.5, MAX_PITCH*FRACTIONONE)); + mind(srcRate*ALdouble{FRACTIONONE}/dstRate + 0.5, MAX_PITCH*FRACTIONONE)); converter->mIncrement = maxi(step, 1); if(converter->mIncrement == FRACTIONONE) converter->mResample = Resample_; diff --git a/alc/converter.h b/alc/converter.h index 62f09af1..46e57f10 100644 --- a/alc/converter.h +++ b/alc/converter.h @@ -39,13 +39,7 @@ struct SampleConverter { ALuint convert(const ALvoid **src, ALuint *srcframes, ALvoid *dst, ALuint dstframes); ALuint availableOut(ALuint srcframes) const; - static constexpr size_t Sizeof(size_t length) noexcept - { - return maxz(sizeof(SampleConverter), - al::FlexArray::Sizeof(length, offsetof(SampleConverter, mChan))); - } - - DEF_PLACE_NEWDEL() + DEF_FAM_NEWDEL(SampleConverter, mChan) }; using SampleConverterPtr = std::unique_ptr; diff --git a/alc/hrtf.cpp b/alc/hrtf.cpp index 5a39f686..04818a4f 100644 --- a/alc/hrtf.cpp +++ b/alc/hrtf.cpp @@ -61,22 +61,12 @@ struct HrtfHandle { HrtfHandle(const HrtfHandle&) = delete; HrtfHandle& operator=(const HrtfHandle&) = delete; - static std::unique_ptr Create(size_t fname_len); - static constexpr size_t Sizeof(size_t length) noexcept - { - return maxz(sizeof(HrtfHandle), - al::FlexArray::Sizeof(length, offsetof(HrtfHandle, filename))); - } + static std::unique_ptr Create(size_t fname_len) + { return std::unique_ptr{new (FamCount{fname_len}) HrtfHandle{fname_len}}; } - DEF_PLACE_NEWDEL() + DEF_FAM_NEWDEL(HrtfHandle, filename) }; -std::unique_ptr HrtfHandle::Create(size_t fname_len) -{ - void *ptr{al_calloc(alignof(HrtfHandle), HrtfHandle::Sizeof(fname_len))}; - return std::unique_ptr{new (ptr) HrtfHandle{fname_len}}; -} - namespace { using namespace std::placeholders; @@ -294,8 +284,7 @@ void GetHrtfCoeffs(const HrtfEntry *Hrtf, ALfloat elevation, ALfloat azimuth, AL std::unique_ptr DirectHrtfState::Create(size_t num_chans) { - void *ptr{al_calloc(16, DirectHrtfState::Sizeof(num_chans))}; - return std::unique_ptr{new (ptr) DirectHrtfState{num_chans}}; + return std::unique_ptr{new (FamCount{num_chans}) DirectHrtfState{num_chans}}; } void BuildBFormatHrtf(const HrtfEntry *Hrtf, DirectHrtfState *state, const ALuint NumChannels, diff --git a/alc/hrtf.h b/alc/hrtf.h index 487dca61..85614f2e 100644 --- a/alc/hrtf.h +++ b/alc/hrtf.h @@ -85,10 +85,8 @@ struct DirectHrtfState { DirectHrtfState(size_t numchans) : Coeffs{numchans} { } static std::unique_ptr Create(size_t num_chans); - static constexpr size_t Sizeof(size_t numchans) noexcept - { return al::FlexArray::Sizeof(numchans, offsetof(DirectHrtfState, Coeffs)); } - DEF_PLACE_NEWDEL() + DEF_FAM_NEWDEL(DirectHrtfState, Coeffs) }; struct AngularPoint { diff --git a/alc/ringbuffer.cpp b/alc/ringbuffer.cpp index d99676b8..d61f6129 100644 --- a/alc/ringbuffer.cpp +++ b/alc/ringbuffer.cpp @@ -48,7 +48,7 @@ RingBufferPtr CreateRingBuffer(size_t sz, size_t elem_sz, int limit_writes) if(power_of_two < sz) return nullptr; const size_t bufbytes{power_of_two * elem_sz}; - RingBufferPtr rb{new (al_calloc(16, sizeof(*rb) + bufbytes)) RingBuffer{bufbytes}}; + RingBufferPtr rb{new (FamCount{bufbytes}) RingBuffer{bufbytes}}; rb->mWriteSize = limit_writes ? sz : (power_of_two-1); rb->mSizeMask = power_of_two - 1; rb->mElemSize = elem_sz; diff --git a/alc/ringbuffer.h b/alc/ringbuffer.h index 84139b66..3151fdcb 100644 --- a/alc/ringbuffer.h +++ b/alc/ringbuffer.h @@ -34,8 +34,6 @@ struct RingBuffer { al::FlexArray mBuffer; RingBuffer(const size_t count) : mBuffer{count} { } - RingBuffer(const RingBuffer&) = delete; - RingBuffer& operator=(const RingBuffer&) = delete; /** Reset the read and write pointers to zero. This is not thread safe. */ void reset() noexcept; @@ -84,7 +82,7 @@ struct RingBuffer { /** Advance the write pointer `cnt' places. */ void writeAdvance(size_t cnt) noexcept; - DEF_PLACE_NEWDEL() + DEF_FAM_NEWDEL(RingBuffer, mBuffer) }; using RingBufferPtr = std::unique_ptr; diff --git a/common/almalloc.h b/common/almalloc.h index 785592bd..232294cc 100644 --- a/common/almalloc.h +++ b/common/almalloc.h @@ -27,8 +27,24 @@ void al_free(void *ptr) noexcept; #define DEF_PLACE_NEWDEL() \ void *operator new(size_t /*size*/, void *ptr) noexcept { return ptr; } \ - void operator delete(void *block) noexcept { al_free(block); } \ - void operator delete(void* /*block*/, void* /*ptr*/) noexcept { } + void operator delete(void *block, void*) noexcept { al_free(block); } \ + void operator delete(void *block) noexcept { al_free(block); } + +struct FamCount { size_t mCount; }; + +#define DEF_FAM_NEWDEL(T, FamMem) \ + static constexpr size_t Sizeof(size_t count) noexcept \ + { return decltype(FamMem)::Sizeof(count, offsetof(T, FamMem)); } \ + \ + void *operator new(size_t /*size*/, FamCount fam) \ + { \ + if(void *ret{al_malloc(alignof(T), T::Sizeof(fam.mCount))}) \ + return ret; \ + throw std::bad_alloc(); \ + } \ + void operator delete(void *block, FamCount /*fam*/) { al_free(block); } \ + void operator delete(void *block) noexcept { al_free(block); } + namespace al { -- cgit v1.2.3 From 963580c2d503eab7c6d8f60a367498ff103bfa3e Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 8 Oct 2019 21:52:08 -0700 Subject: Never return null from CreateRingBuffer Allocation failure would already throw a bad_alloc anyway, now a size overflow throws an exception too. --- alc/backends/alsa.cpp | 3 --- alc/backends/coreaudio.cpp | 1 - alc/backends/dsound.cpp | 3 --- alc/backends/jack.cpp | 11 +---------- alc/backends/opensl.cpp | 21 ++++----------------- alc/backends/oss.cpp | 1 - alc/backends/portaudio.cpp | 1 - alc/backends/sndio.cpp | 1 - alc/backends/wasapi.cpp | 5 ----- alc/backends/winmm.cpp | 1 - alc/ringbuffer.cpp | 4 +++- 11 files changed, 8 insertions(+), 44 deletions(-) (limited to 'alc/ringbuffer.cpp') diff --git a/alc/backends/alsa.cpp b/alc/backends/alsa.cpp index 7c6ce4f9..91415c32 100644 --- a/alc/backends/alsa.cpp +++ b/alc/backends/alsa.cpp @@ -981,10 +981,7 @@ void AlsaCapture::open(const ALCchar *name) hp = nullptr; if(needring) - { mRing = CreateRingBuffer(mDevice->BufferSize, mDevice->frameSizeFromFmt(), false); - if(!mRing) throw al::backend_exception{ALC_INVALID_VALUE, "Failed to create ring buffer"}; - } mDevice->DeviceName = name; return; diff --git a/alc/backends/coreaudio.cpp b/alc/backends/coreaudio.cpp index 9e1d4e47..5a0e4027 100644 --- a/alc/backends/coreaudio.cpp +++ b/alc/backends/coreaudio.cpp @@ -570,7 +570,6 @@ void CoreAudioCapture::open(const ALCchar *name) mDevice->Frequency, Resampler::FastBSinc24); mRing = CreateRingBuffer(outputFrameCount, mFrameSize, false); - if(!mRing) throw al::backend_exception{ALC_INVALID_VALUE, "Failed to allocate ring buffer"}; mDevice->DeviceName = name; } diff --git a/alc/backends/dsound.cpp b/alc/backends/dsound.cpp index 005c9584..b74f2d3e 100644 --- a/alc/backends/dsound.cpp +++ b/alc/backends/dsound.cpp @@ -743,10 +743,7 @@ void DSoundCapture::open(const ALCchar *name) if(SUCCEEDED(hr)) mDSC->CreateCaptureBuffer(&DSCBDescription, &mDSCbuffer, nullptr); if(SUCCEEDED(hr)) - { mRing = CreateRingBuffer(mDevice->BufferSize, InputType.Format.nBlockAlign, false); - if(!mRing) hr = DSERR_OUTOFMEMORY; - } if(FAILED(hr)) { diff --git a/alc/backends/jack.cpp b/alc/backends/jack.cpp index 2a22ed84..0814ca8d 100644 --- a/alc/backends/jack.cpp +++ b/alc/backends/jack.cpp @@ -212,11 +212,7 @@ int JackPlayback::bufferSizeNotify(jack_nframes_t numframes) mRing = nullptr; mRing = CreateRingBuffer(bufsize, mDevice->frameSizeFromFmt(), true); - if(!mRing) - { - ERR("Failed to reallocate ringbuffer\n"); - aluHandleDisconnect(mDevice, "Failed to reallocate %u-sample buffer", bufsize); - } + return 0; } @@ -407,11 +403,6 @@ bool JackPlayback::reset() mRing = nullptr; mRing = CreateRingBuffer(bufsize, mDevice->frameSizeFromFmt(), true); - if(!mRing) - { - ERR("Failed to allocate ringbuffer\n"); - return false; - } SetDefaultChannelOrder(mDevice); diff --git a/alc/backends/opensl.cpp b/alc/backends/opensl.cpp index 4e68da27..258443f2 100644 --- a/alc/backends/opensl.cpp +++ b/alc/backends/opensl.cpp @@ -521,14 +521,7 @@ bool OpenSLPlayback::reset() if(SL_RESULT_SUCCESS == result) { const ALuint num_updates{mDevice->BufferSize / mDevice->UpdateSize}; - try { - mRing = CreateRingBuffer(num_updates, mFrameSize*mDevice->UpdateSize, true); - } - catch(std::exception& e) { - ERR("Failed allocating ring buffer %ux%ux%u: %s\n", mDevice->UpdateSize, - num_updates, mFrameSize, e.what()); - result = SL_RESULT_MEMORY_FAILURE; - } + mRing = CreateRingBuffer(num_updates, mFrameSize*mDevice->UpdateSize, true); } if(SL_RESULT_SUCCESS != result) @@ -703,16 +696,10 @@ void OpenSLCapture::open(const ALCchar* name) mDevice->Frequency/100*5)}; ALuint num_updates{(length+update_len-1) / update_len}; - try { - mRing = CreateRingBuffer(num_updates, update_len*mFrameSize, false); + mRing = CreateRingBuffer(num_updates, update_len*mFrameSize, false); - mDevice->UpdateSize = update_len; - mDevice->BufferSize = static_cast(mRing->writeSpace() * update_len); - } - catch(std::exception& e) { - ERR("Failed to allocate ring buffer: %s\n", e.what()); - result = SL_RESULT_MEMORY_FAILURE; - } + mDevice->UpdateSize = update_len; + mDevice->BufferSize = static_cast(mRing->writeSpace() * update_len); } if(SL_RESULT_SUCCESS == result) { diff --git a/alc/backends/oss.cpp b/alc/backends/oss.cpp index 856aceb0..59cc44e4 100644 --- a/alc/backends/oss.cpp +++ b/alc/backends/oss.cpp @@ -612,7 +612,6 @@ void OSScapture::open(const ALCchar *name) ossFormat}; mRing = CreateRingBuffer(mDevice->BufferSize, frameSize, false); - if(!mRing) throw al::backend_exception{ALC_INVALID_VALUE, "Failed to create ring buffer"}; mDevice->DeviceName = name; } diff --git a/alc/backends/portaudio.cpp b/alc/backends/portaudio.cpp index 7c60d2bb..f50f1f16 100644 --- a/alc/backends/portaudio.cpp +++ b/alc/backends/portaudio.cpp @@ -286,7 +286,6 @@ void PortCapture::open(const ALCchar *name) ALuint frame_size{mDevice->frameSizeFromFmt()}; mRing = CreateRingBuffer(samples, frame_size, false); - if(!mRing) throw al::backend_exception{ALC_INVALID_VALUE, "Failed to create ring buffer"}; auto devidopt = ConfigValueInt(nullptr, "port", "capture"); if(devidopt && *devidopt >= 0) mParams.device = *devidopt; diff --git a/alc/backends/sndio.cpp b/alc/backends/sndio.cpp index 026ff2b9..7799316f 100644 --- a/alc/backends/sndio.cpp +++ b/alc/backends/sndio.cpp @@ -393,7 +393,6 @@ void SndioCapture::open(const ALCchar *name) mDevice->Frequency, par.sig?'s':'u', par.bits, par.rchan, par.rate}; mRing = CreateRingBuffer(mDevice->BufferSize, par.bps*par.rchan, false); - if(!mRing) throw al::backend_exception{ALC_OUT_OF_MEMORY, "Failed to allocate ring buffer"}; SetDefaultChannelOrder(mDevice); diff --git a/alc/backends/wasapi.cpp b/alc/backends/wasapi.cpp index 2c4fe130..37a547af 100644 --- a/alc/backends/wasapi.cpp +++ b/alc/backends/wasapi.cpp @@ -1601,11 +1601,6 @@ HRESULT WasapiCapture::resetProxy() buffer_len = maxu(mDevice->BufferSize, buffer_len); mRing = CreateRingBuffer(buffer_len, mDevice->frameSizeFromFmt(), false); - if(!mRing) - { - ERR("Failed to allocate capture ring buffer\n"); - return E_OUTOFMEMORY; - } hr = mClient->SetEventHandle(mNotifyEvent); if(FAILED(hr)) diff --git a/alc/backends/winmm.cpp b/alc/backends/winmm.cpp index dde74304..c2ccbc05 100644 --- a/alc/backends/winmm.cpp +++ b/alc/backends/winmm.cpp @@ -519,7 +519,6 @@ void WinMMCapture::open(const ALCchar *name) CapturedDataSize = static_cast(maxz(CapturedDataSize, BufferSize*mWaveBuffer.size())); mRing = CreateRingBuffer(CapturedDataSize, mFormat.nBlockAlign, false); - if(!mRing) throw al::backend_exception{ALC_INVALID_VALUE, "Could not create ring buffer"}; al_free(mWaveBuffer[0].lpData); mWaveBuffer[0] = WAVEHDR{}; diff --git a/alc/ringbuffer.cpp b/alc/ringbuffer.cpp index d61f6129..1f72f4b1 100644 --- a/alc/ringbuffer.cpp +++ b/alc/ringbuffer.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include "almalloc.h" @@ -45,7 +46,8 @@ RingBufferPtr CreateRingBuffer(size_t sz, size_t elem_sz, int limit_writes) #endif } ++power_of_two; - if(power_of_two < sz) return nullptr; + if(power_of_two <= sz || power_of_two > std::numeric_limits::max()/elem_sz) + throw std::overflow_error{"Ring buffer size overflow"}; const size_t bufbytes{power_of_two * elem_sz}; RingBufferPtr rb{new (FamCount{bufbytes}) RingBuffer{bufbytes}}; -- cgit v1.2.3