Pass a span of pointers to the UHJ/SuperStereo decoder
This commit is contained in:
parent
1337f050dd
commit
a271484e7c
@ -183,8 +183,9 @@ struct DeviceBase {
|
|||||||
/* Temp storage used for mixer processing. */
|
/* Temp storage used for mixer processing. */
|
||||||
static constexpr size_t MixerLineSize{BufferLineSize + MaxResamplerPadding +
|
static constexpr size_t MixerLineSize{BufferLineSize + MaxResamplerPadding +
|
||||||
UhjDecoder::sFilterDelay};
|
UhjDecoder::sFilterDelay};
|
||||||
|
static constexpr size_t MixerChannelsMax{16};
|
||||||
using MixerBufferLine = std::array<float,MixerLineSize>;
|
using MixerBufferLine = std::array<float,MixerLineSize>;
|
||||||
alignas(16) std::array<MixerBufferLine,16> mSampleData;
|
alignas(16) std::array<MixerBufferLine,MixerChannelsMax> mSampleData;
|
||||||
|
|
||||||
alignas(16) float ResampledData[BufferLineSize];
|
alignas(16) float ResampledData[BufferLineSize];
|
||||||
alignas(16) float FilteredData[BufferLineSize];
|
alignas(16) float FilteredData[BufferLineSize];
|
||||||
|
@ -101,15 +101,15 @@ void UhjEncoder::encode(float *LeftOut, float *RightOut, const FloatBufferLine *
|
|||||||
* where j is a +90 degree phase shift. 3-channel UHJ excludes Q, while 2-
|
* where j is a +90 degree phase shift. 3-channel UHJ excludes Q, while 2-
|
||||||
* channel excludes Q and T.
|
* channel excludes Q and T.
|
||||||
*/
|
*/
|
||||||
void UhjDecoder::decode(const al::span<BufferLine> samples, const size_t offset,
|
void UhjDecoder::decode(const al::span<float*> samples, const size_t samplesToDo,
|
||||||
const size_t samplesToDo, const size_t forwardSamples)
|
const size_t forwardSamples)
|
||||||
{
|
{
|
||||||
ASSUME(samplesToDo > 0);
|
ASSUME(samplesToDo > 0);
|
||||||
|
|
||||||
{
|
{
|
||||||
const float *RESTRICT left{samples[0].data() + offset};
|
const float *RESTRICT left{al::assume_aligned<16>(samples[0])};
|
||||||
const float *RESTRICT right{samples[1].data() + offset};
|
const float *RESTRICT right{al::assume_aligned<16>(samples[1])};
|
||||||
const float *RESTRICT t{samples[2].data() + offset};
|
const float *RESTRICT t{al::assume_aligned<16>(samples[2])};
|
||||||
|
|
||||||
/* S = Left + Right */
|
/* S = Left + Right */
|
||||||
for(size_t i{0};i < samplesToDo+sFilterDelay;++i)
|
for(size_t i{0};i < samplesToDo+sFilterDelay;++i)
|
||||||
@ -124,9 +124,9 @@ void UhjDecoder::decode(const al::span<BufferLine> samples, const size_t offset,
|
|||||||
mT[i] = t[i];
|
mT[i] = t[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
float *RESTRICT woutput{samples[0].data() + offset};
|
float *RESTRICT woutput{al::assume_aligned<16>(samples[0])};
|
||||||
float *RESTRICT xoutput{samples[1].data() + offset};
|
float *RESTRICT xoutput{al::assume_aligned<16>(samples[1])};
|
||||||
float *RESTRICT youtput{samples[2].data() + offset};
|
float *RESTRICT youtput{al::assume_aligned<16>(samples[2])};
|
||||||
|
|
||||||
/* Precompute j(0.828331*D + 0.767820*T) and store in xoutput. */
|
/* Precompute j(0.828331*D + 0.767820*T) and store in xoutput. */
|
||||||
auto tmpiter = std::copy(mDTHistory.cbegin(), mDTHistory.cend(), mTemp.begin());
|
auto tmpiter = std::copy(mDTHistory.cbegin(), mDTHistory.cend(), mTemp.begin());
|
||||||
@ -154,7 +154,7 @@ void UhjDecoder::decode(const al::span<BufferLine> samples, const size_t offset,
|
|||||||
|
|
||||||
if(samples.size() > 3)
|
if(samples.size() > 3)
|
||||||
{
|
{
|
||||||
float *RESTRICT zoutput{samples[3].data() + offset};
|
float *RESTRICT zoutput{al::assume_aligned<16>(samples[3])};
|
||||||
/* Z = 1.023332*Q */
|
/* Z = 1.023332*Q */
|
||||||
for(size_t i{0};i < samplesToDo;++i)
|
for(size_t i{0};i < samplesToDo;++i)
|
||||||
zoutput[i] = 1.023332f*zoutput[i];
|
zoutput[i] = 1.023332f*zoutput[i];
|
||||||
@ -174,14 +174,14 @@ void UhjDecoder::decode(const al::span<BufferLine> samples, const size_t offset,
|
|||||||
* where j is a +90 degree phase shift. w is a variable control for the
|
* where j is a +90 degree phase shift. w is a variable control for the
|
||||||
* resulting stereo width, with the range 0 <= w <= 0.7.
|
* resulting stereo width, with the range 0 <= w <= 0.7.
|
||||||
*/
|
*/
|
||||||
void UhjDecoder::decodeStereo(const al::span<BufferLine> samples, const size_t offset,
|
void UhjDecoder::decodeStereo(const al::span<float*> samples, const size_t samplesToDo,
|
||||||
const size_t samplesToDo, const size_t forwardSamples)
|
const size_t forwardSamples)
|
||||||
{
|
{
|
||||||
ASSUME(samplesToDo > 0);
|
ASSUME(samplesToDo > 0);
|
||||||
|
|
||||||
{
|
{
|
||||||
const float *RESTRICT left{samples[0].data() + offset};
|
const float *RESTRICT left{al::assume_aligned<16>(samples[0])};
|
||||||
const float *RESTRICT right{samples[1].data() + offset};
|
const float *RESTRICT right{al::assume_aligned<16>(samples[1])};
|
||||||
|
|
||||||
for(size_t i{0};i < samplesToDo+sFilterDelay;++i)
|
for(size_t i{0};i < samplesToDo+sFilterDelay;++i)
|
||||||
mS[i] = left[i] + right[i];
|
mS[i] = left[i] + right[i];
|
||||||
@ -212,9 +212,9 @@ void UhjDecoder::decodeStereo(const al::span<BufferLine> samples, const size_t o
|
|||||||
mCurrentWidth = wtarget;
|
mCurrentWidth = wtarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
float *RESTRICT woutput{samples[0].data() + offset};
|
float *RESTRICT woutput{al::assume_aligned<16>(samples[0])};
|
||||||
float *RESTRICT xoutput{samples[1].data() + offset};
|
float *RESTRICT xoutput{al::assume_aligned<16>(samples[1])};
|
||||||
float *RESTRICT youtput{samples[2].data() + offset};
|
float *RESTRICT youtput{al::assume_aligned<16>(samples[2])};
|
||||||
|
|
||||||
/* Precompute j*D and store in xoutput. */
|
/* Precompute j*D and store in xoutput. */
|
||||||
auto tmpiter = std::copy(mDTHistory.cbegin(), mDTHistory.cend(), mTemp.begin());
|
auto tmpiter = std::copy(mDTHistory.cbegin(), mDTHistory.cend(), mTemp.begin());
|
||||||
|
@ -66,7 +66,7 @@ struct UhjDecoder : public UhjFilterBase {
|
|||||||
* reconstructed from 2-channel UHJ should not be run through a normal
|
* reconstructed from 2-channel UHJ should not be run through a normal
|
||||||
* B-Format decoder, as it needs different shelf filters.
|
* B-Format decoder, as it needs different shelf filters.
|
||||||
*/
|
*/
|
||||||
void decode(const al::span<BufferLine> samples, const size_t offset, const size_t samplesToDo,
|
void decode(const al::span<float*> samples, const size_t samplesToDo,
|
||||||
const size_t forwardSamples);
|
const size_t forwardSamples);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,11 +75,11 @@ struct UhjDecoder : public UhjFilterBase {
|
|||||||
* should contain 3 channels, the first two being the left and right stereo
|
* should contain 3 channels, the first two being the left and right stereo
|
||||||
* channels, and the third left empty.
|
* channels, and the third left empty.
|
||||||
*/
|
*/
|
||||||
void decodeStereo(const al::span<BufferLine> samples, const size_t offset,
|
void decodeStereo(const al::span<float*> samples, const size_t samplesToDo,
|
||||||
const size_t samplesToDo, const size_t forwardSamples);
|
const size_t forwardSamples);
|
||||||
|
|
||||||
using DecoderFunc = void (UhjDecoder::*)(const al::span<BufferLine> samples,
|
using DecoderFunc = void (UhjDecoder::*)(const al::span<float*> samples,
|
||||||
const size_t offset, const size_t samplesToDo, const size_t forwardSamples);
|
const size_t samplesToDo, const size_t forwardSamples);
|
||||||
|
|
||||||
DEF_NEWDEL(UhjDecoder)
|
DEF_NEWDEL(UhjDecoder)
|
||||||
};
|
};
|
||||||
|
@ -53,6 +53,7 @@ struct CopyTag;
|
|||||||
|
|
||||||
static_assert(!(sizeof(DeviceBase::MixerBufferLine)&15),
|
static_assert(!(sizeof(DeviceBase::MixerBufferLine)&15),
|
||||||
"DeviceBase::MixerBufferLine must be a multiple of 16 bytes");
|
"DeviceBase::MixerBufferLine must be a multiple of 16 bytes");
|
||||||
|
static_assert(!(MaxResamplerEdge&3), "MaxResamplerEdge is not a multiple of 4");
|
||||||
|
|
||||||
Resampler ResamplerDefault{Resampler::Linear};
|
Resampler ResamplerDefault{Resampler::Linear};
|
||||||
|
|
||||||
@ -627,9 +628,13 @@ void Voice::mix(const State vstate, ContextBase *Context, const uint SamplesToDo
|
|||||||
|
|
||||||
if(mDecoder)
|
if(mDecoder)
|
||||||
{
|
{
|
||||||
|
std::array<float*,DeviceBase::MixerChannelsMax> chanptrs;
|
||||||
|
std::transform(MixingSamples.begin(), MixingSamples.end(), chanptrs.begin(),
|
||||||
|
[](DeviceBase::MixerBufferLine &bufline) noexcept -> float*
|
||||||
|
{ return bufline.data() + MaxResamplerEdge; });
|
||||||
const size_t srcOffset{(increment*DstBufferSize + DataPosFrac)>>MixerFracBits};
|
const size_t srcOffset{(increment*DstBufferSize + DataPosFrac)>>MixerFracBits};
|
||||||
SrcBufferSize = SrcBufferSize - PostPadding + MaxResamplerEdge;
|
SrcBufferSize = SrcBufferSize - PostPadding + MaxResamplerEdge;
|
||||||
((*mDecoder).*mDecoderFunc)(MixingSamples, MaxResamplerEdge, SrcBufferSize,
|
((*mDecoder).*mDecoderFunc)({chanptrs.data(), MixingSamples.size()}, SrcBufferSize,
|
||||||
srcOffset * likely(vstate == Playing));
|
srcOffset * likely(vstate == Playing));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user