Use an AL-specific buffer queue item struct for sources
This commit is contained in:
parent
6151d11253
commit
71e6bcbd62
@ -184,7 +184,7 @@ void UpdateSourceProps(const ALsource *source, Voice *voice, ALCcontext *context
|
||||
int64_t GetSourceSampleOffset(ALsource *Source, ALCcontext *context, nanoseconds *clocktime)
|
||||
{
|
||||
ALCdevice *device{context->mDevice.get()};
|
||||
const BufferlistItem *Current{};
|
||||
const VoiceBufferItem *Current{};
|
||||
uint64_t readPos{};
|
||||
ALuint refcount;
|
||||
Voice *voice;
|
||||
@ -223,7 +223,7 @@ int64_t GetSourceSampleOffset(ALsource *Source, ALCcontext *context, nanoseconds
|
||||
double GetSourceSecOffset(ALsource *Source, ALCcontext *context, nanoseconds *clocktime)
|
||||
{
|
||||
ALCdevice *device{context->mDevice.get()};
|
||||
const BufferlistItem *Current{};
|
||||
const VoiceBufferItem *Current{};
|
||||
uint64_t readPos{};
|
||||
ALuint refcount;
|
||||
Voice *voice;
|
||||
@ -245,7 +245,7 @@ double GetSourceSecOffset(ALsource *Source, ALCcontext *context, nanoseconds *cl
|
||||
if(!voice)
|
||||
return 0.0f;
|
||||
|
||||
const BufferStorage *BufferFmt{nullptr};
|
||||
const ALbuffer *BufferFmt{nullptr};
|
||||
auto BufferList = Source->mQueue.cbegin();
|
||||
while(BufferList != Source->mQueue.cend() && std::addressof(*BufferList) != Current)
|
||||
{
|
||||
@ -272,7 +272,7 @@ double GetSourceSecOffset(ALsource *Source, ALCcontext *context, nanoseconds *cl
|
||||
double GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *context)
|
||||
{
|
||||
ALCdevice *device{context->mDevice.get()};
|
||||
const BufferlistItem *Current{};
|
||||
const VoiceBufferItem *Current{};
|
||||
ALuint readPos{};
|
||||
ALuint readPosFrac{};
|
||||
ALuint refcount;
|
||||
@ -294,20 +294,17 @@ double GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *context)
|
||||
if(!voice)
|
||||
return 0.0;
|
||||
|
||||
auto BufferList = Source->mQueue.cbegin();
|
||||
const ALbuffer *BufferFmt{nullptr};
|
||||
auto BufferList = Source->mQueue.cbegin();
|
||||
while(BufferList != Source->mQueue.cend() && std::addressof(*BufferList) != Current)
|
||||
{
|
||||
if(!BufferFmt)
|
||||
BufferFmt = static_cast<const ALbuffer*>(BufferList->mBuffer);
|
||||
|
||||
if(!BufferFmt) BufferFmt = BufferList->mBuffer;
|
||||
readPos += BufferList->mSampleLen;
|
||||
|
||||
++BufferList;
|
||||
}
|
||||
while(BufferList != Source->mQueue.cend() && !BufferFmt)
|
||||
{
|
||||
BufferFmt = static_cast<const ALbuffer*>(BufferList->mBuffer);
|
||||
BufferFmt = BufferList->mBuffer;
|
||||
++BufferList;
|
||||
}
|
||||
assert(BufferFmt != nullptr);
|
||||
@ -355,7 +352,7 @@ double GetSourceOffset(ALsource *Source, ALenum name, ALCcontext *context)
|
||||
|
||||
struct VoicePos {
|
||||
ALuint pos, frac;
|
||||
BufferlistItem *bufferitem;
|
||||
VoiceBufferItem *bufferitem;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -365,15 +362,15 @@ struct VoicePos {
|
||||
* using the givem offset type and offset. If the offset is out of range,
|
||||
* returns an empty optional.
|
||||
*/
|
||||
al::optional<VoicePos> GetSampleOffset(al::deque<BufferlistItem> &BufferList, ALenum OffsetType,
|
||||
al::optional<VoicePos> GetSampleOffset(al::deque<ALbufferQueueItem> &BufferList, ALenum OffsetType,
|
||||
double Offset)
|
||||
{
|
||||
/* Find the first valid Buffer in the Queue */
|
||||
const ALbuffer *BufferFmt{nullptr};
|
||||
for(auto &item : BufferList)
|
||||
{
|
||||
BufferFmt = static_cast<const ALbuffer*>(item.mBuffer);
|
||||
if(BufferFmt != nullptr) break;
|
||||
BufferFmt = item.mBuffer;
|
||||
if(BufferFmt) break;
|
||||
}
|
||||
if(!BufferFmt)
|
||||
return al::nullopt;
|
||||
@ -435,13 +432,13 @@ al::optional<VoicePos> GetSampleOffset(al::deque<BufferlistItem> &BufferList, AL
|
||||
}
|
||||
|
||||
|
||||
void InitVoice(Voice *voice, ALsource *source, BufferlistItem *BufferList, ALCcontext *context,
|
||||
void InitVoice(Voice *voice, ALsource *source, ALbufferQueueItem *BufferList, ALCcontext *context,
|
||||
ALCdevice *device)
|
||||
{
|
||||
voice->mLoopBuffer.store(source->Looping ? &source->mQueue.front() : nullptr,
|
||||
std::memory_order_relaxed);
|
||||
|
||||
BufferStorage *buffer{BufferList->mBuffer};
|
||||
ALbuffer *buffer{BufferList->mBuffer};
|
||||
ALuint num_channels{buffer->channelsFromFmt()};
|
||||
voice->mFrequency = buffer->mSampleRate;
|
||||
voice->mFmtChannels = buffer->mChannels;
|
||||
@ -1328,7 +1325,7 @@ bool SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
|
||||
{
|
||||
ALCdevice *device{Context->mDevice.get()};
|
||||
ALeffectslot *slot{nullptr};
|
||||
al::deque<BufferlistItem> oldlist{};
|
||||
al::deque<ALbufferQueueItem> oldlist;
|
||||
std::unique_lock<std::mutex> slotlock;
|
||||
float fvals[6];
|
||||
|
||||
@ -1395,21 +1392,21 @@ bool SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
|
||||
"Setting already-set callback buffer %u", buffer->id);
|
||||
|
||||
/* Add the selected buffer to a one-item queue */
|
||||
al::deque<BufferlistItem> newlist;
|
||||
al::deque<ALbufferQueueItem> newlist;
|
||||
newlist.emplace_back();
|
||||
newlist.back().mCallback = buffer->mCallback;
|
||||
newlist.back().mUserData = buffer->mUserData;
|
||||
newlist.back().mSampleLen = buffer->mSampleLen;
|
||||
newlist.back().mLoopStart = buffer->mLoopStart;
|
||||
newlist.back().mLoopEnd = buffer->mLoopEnd;
|
||||
newlist.back().mSamples = buffer->mData;
|
||||
newlist.back().mSamples = buffer->mData.data();
|
||||
newlist.back().mBuffer = buffer;
|
||||
IncrementRef(buffer->ref);
|
||||
|
||||
/* Source is now Static */
|
||||
Source->SourceType = AL_STATIC;
|
||||
oldlist = std::move(Source->mQueue);
|
||||
Source->mQueue = std::move(newlist);
|
||||
Source->mQueue.swap(oldlist);
|
||||
Source->mQueue.swap(newlist);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1421,7 +1418,7 @@ bool SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
|
||||
/* Delete all elements in the previous queue */
|
||||
for(auto &item : oldlist)
|
||||
{
|
||||
if(auto *buffer{static_cast<ALbuffer*>(item.mBuffer)})
|
||||
if(ALbuffer *buffer{item.mBuffer})
|
||||
DecrementRef(buffer->ref);
|
||||
}
|
||||
return true;
|
||||
@ -1972,9 +1969,9 @@ bool GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
|
||||
case AL_BUFFER:
|
||||
CHECKSIZE(values, 1);
|
||||
{
|
||||
BufferlistItem *BufferList{(Source->SourceType == AL_STATIC)
|
||||
ALbufferQueueItem *BufferList{(Source->SourceType == AL_STATIC)
|
||||
? &Source->mQueue.front() : nullptr};
|
||||
ALbuffer *buffer{BufferList ? static_cast<ALbuffer*>(BufferList->mBuffer) : nullptr};
|
||||
ALbuffer *buffer{BufferList ? BufferList->mBuffer : nullptr};
|
||||
values[0] = buffer ? static_cast<int>(buffer->id) : 0;
|
||||
}
|
||||
return true;
|
||||
@ -2003,7 +2000,7 @@ bool GetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a
|
||||
int played{0};
|
||||
if(Source->state != AL_INITIAL)
|
||||
{
|
||||
const BufferlistItem *Current{nullptr};
|
||||
const VoiceBufferItem *Current{nullptr};
|
||||
if(Voice *voice{GetSourceVoice(Source, Context)})
|
||||
Current = voice->mCurrentBuffer.load(std::memory_order_relaxed);
|
||||
for(auto &item : Source->mQueue)
|
||||
@ -2921,9 +2918,8 @@ START_API_FUNC
|
||||
auto BufferList = source->mQueue.begin();
|
||||
for(;BufferList != source->mQueue.end();++BufferList)
|
||||
{
|
||||
if(BufferList->mSampleLen != 0) break;
|
||||
BufferStorage *buffer{BufferList->mBuffer};
|
||||
if(buffer && buffer->mCallback) break;
|
||||
if(BufferList->mSampleLen != 0 || BufferList->mCallback)
|
||||
break;
|
||||
}
|
||||
|
||||
/* If there's nothing to play, go right to stopped. */
|
||||
@ -3008,7 +3004,7 @@ START_API_FUNC
|
||||
voice->mPosition.store(vpos->pos, std::memory_order_relaxed);
|
||||
voice->mPositionFrac.store(vpos->frac, std::memory_order_relaxed);
|
||||
voice->mCurrentBuffer.store(vpos->bufferitem, std::memory_order_relaxed);
|
||||
if(vpos->pos != 0 || vpos->frac != 0 || vpos->bufferitem != &source->mQueue.front())
|
||||
if(vpos->pos!=0 || vpos->frac!=0 || vpos->bufferitem!=&source->mQueue.front())
|
||||
voice->mFlags |= VoiceIsFading;
|
||||
}
|
||||
}
|
||||
@ -3255,13 +3251,13 @@ START_API_FUNC
|
||||
ALbuffer *BufferFmt{nullptr};
|
||||
for(auto &item : source->mQueue)
|
||||
{
|
||||
BufferFmt = static_cast<ALbuffer*>(item.mBuffer);
|
||||
BufferFmt = item.mBuffer;
|
||||
if(BufferFmt) break;
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> buflock{device->BufferLock};
|
||||
const size_t NewListStart{source->mQueue.size()};
|
||||
BufferlistItem *BufferList{nullptr};
|
||||
ALbufferQueueItem *BufferList{nullptr};
|
||||
for(ALsizei i{0};i < nb;i++)
|
||||
{
|
||||
bool fmt_mismatch{false};
|
||||
@ -3289,7 +3285,7 @@ START_API_FUNC
|
||||
if(!buffer) continue;
|
||||
BufferList->mSampleLen = buffer->mSampleLen;
|
||||
BufferList->mLoopEnd = buffer->mSampleLen;
|
||||
BufferList->mSamples = buffer->mData;
|
||||
BufferList->mSamples = buffer->mData.data();
|
||||
BufferList->mBuffer = buffer;
|
||||
IncrementRef(buffer->ref);
|
||||
|
||||
@ -3325,7 +3321,7 @@ START_API_FUNC
|
||||
auto iter = source->mQueue.begin() + ptrdiff_t(NewListStart);
|
||||
for(;iter != source->mQueue.end();++iter)
|
||||
{
|
||||
if(auto *buf{static_cast<ALbuffer*>(iter->mBuffer)})
|
||||
if(ALbuffer *buf{iter->mBuffer})
|
||||
DecrementRef(buf->ref);
|
||||
}
|
||||
source->mQueue.resize(NewListStart);
|
||||
@ -3371,7 +3367,7 @@ START_API_FUNC
|
||||
uint processed{0u};
|
||||
if LIKELY(source->state != AL_INITIAL)
|
||||
{
|
||||
BufferlistItem *Current{nullptr};
|
||||
VoiceBufferItem *Current{nullptr};
|
||||
if(Voice *voice{GetSourceVoice(source, context.get())})
|
||||
Current = voice->mCurrentBuffer.load(std::memory_order_relaxed);
|
||||
for(auto &item : source->mQueue)
|
||||
@ -3387,7 +3383,7 @@ START_API_FUNC
|
||||
|
||||
do {
|
||||
auto &head = source->mQueue.front();
|
||||
if(auto *buffer{static_cast<ALbuffer*>(head.mBuffer)})
|
||||
if(ALbuffer *buffer{head.mBuffer})
|
||||
{
|
||||
*(buffers++) = buffer->id;
|
||||
DecrementRef(buffer->ref);
|
||||
@ -3424,7 +3420,7 @@ ALsource::~ALsource()
|
||||
{
|
||||
for(auto &item : mQueue)
|
||||
{
|
||||
if(auto *buffer{static_cast<ALbuffer*>(item.mBuffer)})
|
||||
if(ALbuffer *buffer{item.mBuffer})
|
||||
DecrementRef(buffer->ref);
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,6 @@
|
||||
|
||||
struct ALbuffer;
|
||||
struct ALeffectslot;
|
||||
struct BufferlistItem;
|
||||
|
||||
namespace al {
|
||||
|
||||
@ -35,6 +34,12 @@ using deque = std::deque<T, al::allocator<T>>;
|
||||
|
||||
#define INVALID_VOICE_IDX static_cast<ALuint>(-1)
|
||||
|
||||
struct ALbufferQueueItem : public VoiceBufferItem {
|
||||
ALbuffer *mBuffer{nullptr};
|
||||
|
||||
DISABLE_ALLOC()
|
||||
};
|
||||
|
||||
|
||||
struct ALsource {
|
||||
/** Source properties. */
|
||||
@ -108,7 +113,7 @@ struct ALsource {
|
||||
ALenum state{AL_INITIAL};
|
||||
|
||||
/** Source Buffer Queue head. */
|
||||
al::deque<BufferlistItem> mQueue;
|
||||
al::deque<ALbufferQueueItem> mQueue;
|
||||
|
||||
std::atomic_flag PropsClean;
|
||||
|
||||
|
@ -4,8 +4,6 @@
|
||||
#include <atomic>
|
||||
|
||||
#include "albyte.h"
|
||||
#include "almalloc.h"
|
||||
#include "alspan.h"
|
||||
|
||||
|
||||
using uint = unsigned int;
|
||||
@ -71,22 +69,4 @@ struct BufferStorage {
|
||||
{ return mChannels == FmtBFormat2D || mChannels == FmtBFormat3D; }
|
||||
};
|
||||
|
||||
|
||||
struct BufferlistItem {
|
||||
std::atomic<BufferlistItem*> mNext{nullptr};
|
||||
|
||||
CallbackType mCallback{nullptr};
|
||||
void *mUserData{nullptr};
|
||||
|
||||
uint mSampleLen{0u};
|
||||
uint mLoopStart{0u};
|
||||
uint mLoopEnd{0u};
|
||||
|
||||
al::span<al::byte> mSamples;
|
||||
|
||||
BufferStorage *mBuffer{nullptr};
|
||||
|
||||
DEF_NEWDEL(BufferlistItem)
|
||||
};
|
||||
|
||||
#endif /* ALC_BUFFER_STORAGE_H */
|
||||
|
@ -234,7 +234,7 @@ void LoadSamples(float *RESTRICT dst, const al::byte *src, const size_t srcstep,
|
||||
#undef HANDLE_FMT
|
||||
}
|
||||
|
||||
float *LoadBufferStatic(BufferlistItem *buffer, BufferlistItem *&bufferLoopItem,
|
||||
float *LoadBufferStatic(VoiceBufferItem *buffer, VoiceBufferItem *&bufferLoopItem,
|
||||
const size_t numChannels, const FmtType sampleType, const size_t sampleSize, const size_t chan,
|
||||
size_t dataPosInt, al::span<float> srcBuffer)
|
||||
{
|
||||
@ -250,9 +250,7 @@ float *LoadBufferStatic(BufferlistItem *buffer, BufferlistItem *&bufferLoopItem,
|
||||
/* Load what's left to play from the buffer */
|
||||
const size_t DataRem{minz(srcBuffer.size(), buffer->mSampleLen-dataPosInt)};
|
||||
|
||||
const al::byte *Data{buffer->mSamples.data()};
|
||||
Data += (dataPosInt*numChannels + chan)*sampleSize;
|
||||
|
||||
const al::byte *Data{buffer->mSamples + (dataPosInt*numChannels + chan)*sampleSize};
|
||||
LoadSamples(srcBuffer.data(), Data, numChannels, sampleType, DataRem);
|
||||
srcBuffer = srcBuffer.subspan(DataRem);
|
||||
}
|
||||
@ -261,9 +259,7 @@ float *LoadBufferStatic(BufferlistItem *buffer, BufferlistItem *&bufferLoopItem,
|
||||
/* Load what's left of this loop iteration */
|
||||
const size_t DataRem{minz(srcBuffer.size(), LoopEnd-dataPosInt)};
|
||||
|
||||
const al::byte *Data{buffer->mSamples.data()};
|
||||
Data += (dataPosInt*numChannels + chan)*sampleSize;
|
||||
|
||||
const al::byte *Data{buffer->mSamples + (dataPosInt*numChannels + chan)*sampleSize};
|
||||
LoadSamples(srcBuffer.data(), Data, numChannels, sampleType, DataRem);
|
||||
srcBuffer = srcBuffer.subspan(DataRem);
|
||||
|
||||
@ -273,7 +269,7 @@ float *LoadBufferStatic(BufferlistItem *buffer, BufferlistItem *&bufferLoopItem,
|
||||
{
|
||||
const size_t DataSize{minz(srcBuffer.size(), LoopSize)};
|
||||
|
||||
Data = buffer->mSamples.data() + (LoopStart*numChannels + chan)*sampleSize;
|
||||
Data = buffer->mSamples + (LoopStart*numChannels + chan)*sampleSize;
|
||||
|
||||
LoadSamples(srcBuffer.data(), Data, numChannels, sampleType, DataSize);
|
||||
srcBuffer = srcBuffer.subspan(DataSize);
|
||||
@ -282,22 +278,21 @@ float *LoadBufferStatic(BufferlistItem *buffer, BufferlistItem *&bufferLoopItem,
|
||||
return srcBuffer.begin();
|
||||
}
|
||||
|
||||
float *LoadBufferCallback(BufferlistItem *buffer, const size_t numChannels,
|
||||
float *LoadBufferCallback(VoiceBufferItem *buffer, const size_t numChannels,
|
||||
const FmtType sampleType, const size_t sampleSize, const size_t chan,
|
||||
size_t numCallbackSamples, al::span<float> srcBuffer)
|
||||
{
|
||||
/* Load what's left to play from the buffer */
|
||||
const size_t DataRem{minz(srcBuffer.size(), numCallbackSamples)};
|
||||
|
||||
const al::byte *Data{buffer->mSamples.data() + chan*sampleSize};
|
||||
|
||||
const al::byte *Data{buffer->mSamples + chan*sampleSize};
|
||||
LoadSamples(srcBuffer.data(), Data, numChannels, sampleType, DataRem);
|
||||
srcBuffer = srcBuffer.subspan(DataRem);
|
||||
|
||||
return srcBuffer.begin();
|
||||
}
|
||||
|
||||
float *LoadBufferQueue(BufferlistItem *buffer, BufferlistItem *bufferLoopItem,
|
||||
float *LoadBufferQueue(VoiceBufferItem *buffer, VoiceBufferItem *bufferLoopItem,
|
||||
const size_t numChannels, const FmtType sampleType, const size_t sampleSize, const size_t chan,
|
||||
size_t dataPosInt, al::span<float> srcBuffer)
|
||||
{
|
||||
@ -314,9 +309,7 @@ float *LoadBufferQueue(BufferlistItem *buffer, BufferlistItem *bufferLoopItem,
|
||||
|
||||
const size_t DataSize{minz(srcBuffer.size(), buffer->mSampleLen-dataPosInt)};
|
||||
|
||||
const al::byte *Data{buffer->mSamples.data()};
|
||||
Data += (dataPosInt*numChannels + chan)*sampleSize;
|
||||
|
||||
const al::byte *Data{buffer->mSamples + (dataPosInt*numChannels + chan)*sampleSize};
|
||||
LoadSamples(srcBuffer.data(), Data, numChannels, sampleType, DataSize);
|
||||
srcBuffer = srcBuffer.subspan(DataSize);
|
||||
if(srcBuffer.empty()) break;
|
||||
@ -443,8 +436,8 @@ void Voice::mix(const State vstate, ALCcontext *Context, const uint SamplesToDo)
|
||||
/* Get voice info */
|
||||
uint DataPosInt{mPosition.load(std::memory_order_relaxed)};
|
||||
uint DataPosFrac{mPositionFrac.load(std::memory_order_relaxed)};
|
||||
BufferlistItem *BufferListItem{mCurrentBuffer.load(std::memory_order_relaxed)};
|
||||
BufferlistItem *BufferLoopItem{mLoopBuffer.load(std::memory_order_relaxed)};
|
||||
VoiceBufferItem *BufferListItem{mCurrentBuffer.load(std::memory_order_relaxed)};
|
||||
VoiceBufferItem *BufferLoopItem{mLoopBuffer.load(std::memory_order_relaxed)};
|
||||
const FmtType SampleType{mFmtType};
|
||||
const uint SampleSize{mSampleSize};
|
||||
const uint increment{mStep};
|
||||
@ -724,7 +717,7 @@ void Voice::mix(const State vstate, ALCcontext *Context, const uint SamplesToDo)
|
||||
{
|
||||
const size_t byteOffset{SrcSamplesDone*FrameSize};
|
||||
const size_t byteEnd{mNumCallbackSamples*FrameSize};
|
||||
al::byte *data{BufferListItem->mSamples.data()};
|
||||
al::byte *data{BufferListItem->mSamples};
|
||||
std::copy(data+byteOffset, data+byteEnd, data);
|
||||
mNumCallbackSamples -= SrcSamplesDone;
|
||||
}
|
||||
|
21
alc/voice.h
21
alc/voice.h
@ -74,6 +74,20 @@ struct SendParams {
|
||||
};
|
||||
|
||||
|
||||
struct VoiceBufferItem {
|
||||
std::atomic<VoiceBufferItem*> mNext{nullptr};
|
||||
|
||||
CallbackType mCallback{nullptr};
|
||||
void *mUserData{nullptr};
|
||||
|
||||
uint mSampleLen{0u};
|
||||
uint mLoopStart{0u};
|
||||
uint mLoopEnd{0u};
|
||||
|
||||
al::byte *mSamples{nullptr};
|
||||
};
|
||||
|
||||
|
||||
struct VoiceProps {
|
||||
float Pitch;
|
||||
float Gain;
|
||||
@ -166,12 +180,12 @@ struct Voice {
|
||||
std::atomic<uint> mPositionFrac;
|
||||
|
||||
/* Current buffer queue item being played. */
|
||||
std::atomic<BufferlistItem*> mCurrentBuffer;
|
||||
std::atomic<VoiceBufferItem*> mCurrentBuffer;
|
||||
|
||||
/* Buffer queue item to loop to at end of queue (will be NULL for non-
|
||||
* looping voices).
|
||||
*/
|
||||
std::atomic<BufferlistItem*> mLoopBuffer;
|
||||
std::atomic<VoiceBufferItem*> mLoopBuffer;
|
||||
|
||||
/* Properties for the attached buffer(s). */
|
||||
FmtChannels mFmtChannels;
|
||||
@ -211,8 +225,9 @@ struct Voice {
|
||||
al::vector<ChannelData> mChans{2};
|
||||
|
||||
Voice() = default;
|
||||
Voice(const Voice&) = delete;
|
||||
~Voice() { delete mUpdate.exchange(nullptr, std::memory_order_acq_rel); }
|
||||
|
||||
Voice(const Voice&) = delete;
|
||||
Voice& operator=(const Voice&) = delete;
|
||||
|
||||
void mix(const State vstate, ALCcontext *Context, const uint SamplesToDo);
|
||||
|
Loading…
x
Reference in New Issue
Block a user