Restructure some voice fields
This commit is contained in:
parent
5ac19673db
commit
515a201e30
13
Alc/alc.cpp
13
Alc/alc.cpp
@ -2644,17 +2644,12 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
|
||||
voice->mStep = old_voice->mStep;
|
||||
voice->mResampler = old_voice->mResampler;
|
||||
|
||||
voice->mFlags = old_voice->mFlags;
|
||||
|
||||
std::copy(std::begin(old_voice->mPrevSamples), std::end(old_voice->mPrevSamples),
|
||||
std::begin(voice->mPrevSamples));
|
||||
|
||||
voice->mResampleState = old_voice->mResampleState;
|
||||
|
||||
voice->mAmbiScales = old_voice->mAmbiScales;
|
||||
voice->mAmbiSplitter = old_voice->mAmbiSplitter;
|
||||
std::for_each(voice->mAmbiSplitter.begin(),voice->mAmbiSplitter.end(),
|
||||
std::bind(std::mem_fn(&BandSplitter::clear), _1));
|
||||
voice->mFlags = old_voice->mFlags;
|
||||
|
||||
std::copy(old_voice->mResampleData.begin(), old_voice->mResampleData.end(),
|
||||
voice->mResampleData.end());
|
||||
|
||||
voice->mDirect = old_voice->mDirect;
|
||||
std::copy_n(old_voice->mSend.begin(), s_count, voice->mSend.begin());
|
||||
|
@ -550,14 +550,15 @@ void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCc
|
||||
auto &SrcData = Device->SourceData;
|
||||
|
||||
/* Load the previous samples into the source data first, and clear the rest. */
|
||||
auto srciter = std::copy_n(voice->mPrevSamples[chan].begin(), MAX_RESAMPLE_PADDING,
|
||||
std::begin(SrcData));
|
||||
auto srciter = std::copy_n(voice->mResampleData[chan].mPrevSamples.begin(),
|
||||
MAX_RESAMPLE_PADDING, std::begin(SrcData));
|
||||
std::fill(srciter, std::end(SrcData), 0.0f);
|
||||
|
||||
auto srcdata_end = std::begin(SrcData) + SrcBufferSize;
|
||||
if(!BufferListItem)
|
||||
srciter = std::copy(voice->mPrevSamples[chan].begin()+MAX_RESAMPLE_PADDING,
|
||||
voice->mPrevSamples[chan].end(), srciter);
|
||||
srciter = std::copy(
|
||||
voice->mResampleData[chan].mPrevSamples.begin()+MAX_RESAMPLE_PADDING,
|
||||
voice->mResampleData[chan].mPrevSamples.end(), srciter);
|
||||
else if(isstatic)
|
||||
srciter = LoadBufferStatic(BufferListItem, BufferLoopItem, NumChannels,
|
||||
SampleSize, chan, DataPosInt, srciter, srcdata_end);
|
||||
@ -585,7 +586,8 @@ void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCc
|
||||
|
||||
/* Store the last source samples used for next time. */
|
||||
std::copy_n(&SrcData[(increment*DstBufferSize + DataPosFrac)>>FRACTIONBITS],
|
||||
voice->mPrevSamples[chan].size(), std::begin(voice->mPrevSamples[chan]));
|
||||
voice->mResampleData[chan].mPrevSamples.size(),
|
||||
voice->mResampleData[chan].mPrevSamples.begin());
|
||||
|
||||
/* Resample, then apply ambisonic upsampling as needed. */
|
||||
const ALfloat *ResampledData{Resample(&voice->mResampleState,
|
||||
@ -593,15 +595,15 @@ void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCc
|
||||
Device->ResampledData, DstBufferSize)};
|
||||
if((voice->mFlags&VOICE_IS_AMBISONIC))
|
||||
{
|
||||
const ALfloat hfscale{voice->mAmbiScales[chan]};
|
||||
const ALfloat hfscale{voice->mResampleData[chan].mAmbiScale};
|
||||
/* Beware the evil const_cast. It's safe since it's pointing to
|
||||
* either SrcData or Device->ResampledData (both non-const),
|
||||
* but the resample method takes its input as const float* and
|
||||
* may return it without copying to output, making it currently
|
||||
* unavoidable.
|
||||
*/
|
||||
voice->mAmbiSplitter[chan].applyHfScale(const_cast<ALfloat*>(ResampledData),
|
||||
hfscale, DstBufferSize);
|
||||
voice->mResampleData[chan].mAmbiSplitter.applyHfScale(
|
||||
const_cast<ALfloat*>(ResampledData), hfscale, DstBufferSize);
|
||||
}
|
||||
|
||||
/* Now filter and mix to the appropriate outputs. */
|
||||
|
@ -247,15 +247,17 @@ struct ALvoice {
|
||||
|
||||
ResamplerFunc mResampler;
|
||||
|
||||
ALuint mFlags;
|
||||
|
||||
using ResamplePaddingArray = std::array<ALfloat,MAX_RESAMPLE_PADDING*2>;
|
||||
alignas(16) std::array<ResamplePaddingArray,MAX_INPUT_CHANNELS> mPrevSamples;
|
||||
|
||||
InterpState mResampleState;
|
||||
|
||||
std::array<ALfloat,MAX_INPUT_CHANNELS> mAmbiScales;
|
||||
std::array<BandSplitter,MAX_INPUT_CHANNELS> mAmbiSplitter;
|
||||
ALuint mFlags;
|
||||
|
||||
struct ResampleData {
|
||||
alignas(16) std::array<ALfloat,MAX_RESAMPLE_PADDING*2> mPrevSamples;
|
||||
|
||||
ALfloat mAmbiScale;
|
||||
BandSplitter mAmbiSplitter;
|
||||
};
|
||||
std::array<ResampleData,MAX_INPUT_CHANNELS> mResampleData;
|
||||
|
||||
struct {
|
||||
int FilterType;
|
||||
|
@ -2906,11 +2906,6 @@ START_API_FUNC
|
||||
voice->mSampleSize = BytesFromFmt((*buffer)->mFmtType);
|
||||
}
|
||||
|
||||
/* Clear previous samples. */
|
||||
std::for_each(voice->mPrevSamples.begin(), voice->mPrevSamples.begin()+voice->mNumChannels,
|
||||
[](std::array<ALfloat,MAX_RESAMPLE_PADDING*2> &samples) -> void
|
||||
{ std::fill(std::begin(samples), std::end(samples), 0.0f); });
|
||||
|
||||
/* Clear the stepping value so the mixer knows not to mix this until
|
||||
* the update gets applied.
|
||||
*/
|
||||
@ -2925,31 +2920,45 @@ START_API_FUNC
|
||||
if((voice->mFmtChannels == FmtBFormat2D || voice->mFmtChannels == FmtBFormat3D) &&
|
||||
device->mAmbiOrder > 1)
|
||||
{
|
||||
auto scales = BFormatDec::GetHFOrderScales(1, device->mAmbiOrder);
|
||||
const int *OrderFromChan;
|
||||
if(voice->mFmtChannels == FmtBFormat2D)
|
||||
{
|
||||
static constexpr int Order2DFromChan[MAX_AMBI2D_CHANNELS]{
|
||||
0, 1,1, 2,2, 3,3
|
||||
};
|
||||
const size_t count{Ambi2DChannelsFromOrder(1u)};
|
||||
std::transform(Order2DFromChan, Order2DFromChan+count, voice->mAmbiScales.begin(),
|
||||
[&scales](size_t idx) -> ALfloat { return scales[idx]; });
|
||||
OrderFromChan = Order2DFromChan;
|
||||
}
|
||||
else
|
||||
{
|
||||
static constexpr int OrderFromChan[MAX_AMBI_CHANNELS]{
|
||||
static constexpr int Order3DFromChan[MAX_AMBI_CHANNELS]{
|
||||
0, 1,1,1, 2,2,2,2,2, 3,3,3,3,3,3,3,
|
||||
};
|
||||
const size_t count{Ambi2DChannelsFromOrder(1u)};
|
||||
std::transform(OrderFromChan, OrderFromChan+count, voice->mAmbiScales.begin(),
|
||||
[&scales](size_t idx) -> ALfloat { return scales[idx]; });
|
||||
OrderFromChan = Order3DFromChan;
|
||||
}
|
||||
|
||||
voice->mAmbiSplitter[0].init(400.0f / static_cast<ALfloat>(device->Frequency));
|
||||
std::fill_n(voice->mAmbiSplitter.begin()+1, voice->mNumChannels-1,
|
||||
voice->mAmbiSplitter[0]);
|
||||
BandSplitter splitter;
|
||||
splitter.init(400.0f / static_cast<ALfloat>(device->Frequency));
|
||||
|
||||
const auto scales = BFormatDec::GetHFOrderScales(1, device->mAmbiOrder);
|
||||
auto init_ambi = [scales,&OrderFromChan,&splitter](ALvoice::ResampleData &resdata) -> void
|
||||
{
|
||||
resdata.mPrevSamples.fill(0.0f);
|
||||
resdata.mAmbiScale = scales[*(OrderFromChan++)];
|
||||
resdata.mAmbiSplitter = splitter;
|
||||
};
|
||||
std::for_each(voice->mResampleData.begin(),
|
||||
voice->mResampleData.begin()+voice->mNumChannels, init_ambi);
|
||||
|
||||
voice->mFlags |= VOICE_IS_AMBISONIC;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clear previous samples. */
|
||||
auto clear_prevs = [](ALvoice::ResampleData &resdata) -> void
|
||||
{ resdata.mPrevSamples.fill(0.0f); };
|
||||
std::for_each(voice->mResampleData.begin(),
|
||||
voice->mResampleData.begin()+voice->mNumChannels, clear_prevs);
|
||||
}
|
||||
|
||||
std::fill_n(std::begin(voice->mDirect.Params), voice->mNumChannels, DirectParams{});
|
||||
std::for_each(voice->mSend.begin(), voice->mSend.end(),
|
||||
@ -2959,8 +2968,8 @@ START_API_FUNC
|
||||
|
||||
if(device->AvgSpeakerDist > 0.0f)
|
||||
{
|
||||
ALfloat w1 = SPEEDOFSOUNDMETRESPERSEC /
|
||||
(device->AvgSpeakerDist * device->Frequency);
|
||||
const ALfloat w1{SPEEDOFSOUNDMETRESPERSEC /
|
||||
(device->AvgSpeakerDist * device->Frequency)};
|
||||
std::for_each(voice->mDirect.Params+0, voice->mDirect.Params+voice->mNumChannels,
|
||||
[w1](DirectParams &parms) noexcept -> void
|
||||
{ parms.NFCtrlFilter.init(w1); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user