Restructure some voice fields

This commit is contained in:
Chris Robinson 2019-05-17 20:39:28 -07:00
parent 5ac19673db
commit 515a201e30
4 changed files with 50 additions and 42 deletions

View File

@ -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());

View File

@ -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. */

View File

@ -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;

View File

@ -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); }