Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
183
Src/external_dependencies/openmpt-trunk/soundlib/MixerLoops.cpp
Normal file
183
Src/external_dependencies/openmpt-trunk/soundlib/MixerLoops.cpp
Normal file
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* MixerLoops.cpp
|
||||
* --------------
|
||||
* Purpose: Utility inner loops for mixer-related functionality.
|
||||
* Notes : This file contains performance-critical loops.
|
||||
* Authors: Olivier Lapicque
|
||||
* OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "MixerLoops.h"
|
||||
#include "Snd_defs.h"
|
||||
#include "ModChannel.h"
|
||||
|
||||
|
||||
OPENMPT_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
|
||||
void FloatToStereoMix(const float *pIn1, const float *pIn2, int32 *pOut, uint32 nCount, const float _f2ic)
|
||||
{
|
||||
for(uint32 i=0; i<nCount; ++i)
|
||||
{
|
||||
*pOut++ = (int)(*pIn1++ * _f2ic);
|
||||
*pOut++ = (int)(*pIn2++ * _f2ic);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void StereoMixToFloat(const int32 *pSrc, float *pOut1, float *pOut2, uint32 nCount, const float _i2fc)
|
||||
{
|
||||
for(uint32 i=0; i<nCount; ++i)
|
||||
{
|
||||
*pOut1++ = *pSrc++ * _i2fc;
|
||||
*pOut2++ = *pSrc++ * _i2fc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FloatToMonoMix(const float *pIn, int32 *pOut, uint32 nCount, const float _f2ic)
|
||||
{
|
||||
for(uint32 i=0; i<nCount; ++i)
|
||||
{
|
||||
*pOut++ = (int)(*pIn++ * _f2ic);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MonoMixToFloat(const int32 *pSrc, float *pOut, uint32 nCount, const float _i2fc)
|
||||
{
|
||||
for(uint32 i=0; i<nCount; ++i)
|
||||
{
|
||||
*pOut++ = *pSrc++ * _i2fc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void InitMixBuffer(mixsample_t *pBuffer, uint32 nSamples)
|
||||
{
|
||||
std::memset(pBuffer, 0, nSamples * sizeof(mixsample_t));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void InterleaveFrontRear(mixsample_t *pFrontBuf, mixsample_t *pRearBuf, uint32 nFrames)
|
||||
{
|
||||
// copy backwards as we are writing back into FrontBuf
|
||||
for(int i=nFrames-1; i>=0; i--)
|
||||
{
|
||||
pFrontBuf[i*4+3] = pRearBuf[i*2+1];
|
||||
pFrontBuf[i*4+2] = pRearBuf[i*2+0];
|
||||
pFrontBuf[i*4+1] = pFrontBuf[i*2+1];
|
||||
pFrontBuf[i*4+0] = pFrontBuf[i*2+0];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MonoFromStereo(mixsample_t *pMixBuf, uint32 nSamples)
|
||||
{
|
||||
for(uint32 i=0; i<nSamples; ++i)
|
||||
{
|
||||
pMixBuf[i] = (pMixBuf[i*2] + pMixBuf[i*2+1]) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define OFSDECAYSHIFT 8
|
||||
#define OFSDECAYMASK 0xFF
|
||||
#define OFSTHRESHOLD static_cast<mixsample_t>(1.0 / (1 << 20)) // Decay threshold for floating point mixer
|
||||
|
||||
|
||||
void StereoFill(mixsample_t *pBuffer, uint32 nSamples, mixsample_t &rofs, mixsample_t &lofs)
|
||||
{
|
||||
if((!rofs) && (!lofs))
|
||||
{
|
||||
InitMixBuffer(pBuffer, nSamples*2);
|
||||
return;
|
||||
}
|
||||
for(uint32 i=0; i<nSamples; i++)
|
||||
{
|
||||
#ifdef MPT_INTMIXER
|
||||
// Equivalent to int x_r = (rofs + (rofs > 0 ? 255 : -255)) / 256;
|
||||
const mixsample_t x_r = mpt::rshift_signed(rofs + (mpt::rshift_signed(-rofs, sizeof(mixsample_t) * 8 - 1) & OFSDECAYMASK), OFSDECAYSHIFT);
|
||||
const mixsample_t x_l = mpt::rshift_signed(lofs + (mpt::rshift_signed(-lofs, sizeof(mixsample_t) * 8 - 1) & OFSDECAYMASK), OFSDECAYSHIFT);
|
||||
#else
|
||||
const mixsample_t x_r = rofs * (1.0f / (1 << OFSDECAYSHIFT));
|
||||
const mixsample_t x_l = lofs * (1.0f / (1 << OFSDECAYSHIFT));
|
||||
#endif
|
||||
rofs -= x_r;
|
||||
lofs -= x_l;
|
||||
pBuffer[i*2] = rofs;
|
||||
pBuffer[i*2+1] = lofs;
|
||||
}
|
||||
|
||||
#ifndef MPT_INTMIXER
|
||||
if(fabs(rofs) < OFSTHRESHOLD) rofs = 0;
|
||||
if(fabs(lofs) < OFSTHRESHOLD) lofs = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void EndChannelOfs(ModChannel &chn, mixsample_t *pBuffer, uint32 nSamples)
|
||||
{
|
||||
|
||||
mixsample_t rofs = chn.nROfs;
|
||||
mixsample_t lofs = chn.nLOfs;
|
||||
|
||||
if((!rofs) && (!lofs))
|
||||
{
|
||||
return;
|
||||
}
|
||||
for(uint32 i=0; i<nSamples; i++)
|
||||
{
|
||||
#ifdef MPT_INTMIXER
|
||||
const mixsample_t x_r = mpt::rshift_signed(rofs + (mpt::rshift_signed(-rofs, sizeof(mixsample_t) * 8 - 1) & OFSDECAYMASK), OFSDECAYSHIFT);
|
||||
const mixsample_t x_l = mpt::rshift_signed(lofs + (mpt::rshift_signed(-lofs, sizeof(mixsample_t) * 8 - 1) & OFSDECAYMASK), OFSDECAYSHIFT);
|
||||
#else
|
||||
const mixsample_t x_r = rofs * (1.0f / (1 << OFSDECAYSHIFT));
|
||||
const mixsample_t x_l = lofs * (1.0f / (1 << OFSDECAYSHIFT));
|
||||
#endif
|
||||
rofs -= x_r;
|
||||
lofs -= x_l;
|
||||
pBuffer[i*2] += rofs;
|
||||
pBuffer[i*2+1] += lofs;
|
||||
}
|
||||
#ifndef MPT_INTMIXER
|
||||
if(std::abs(rofs) < OFSTHRESHOLD) rofs = 0;
|
||||
if(std::abs(lofs) < OFSTHRESHOLD) lofs = 0;
|
||||
#endif
|
||||
|
||||
chn.nROfs = rofs;
|
||||
chn.nLOfs = lofs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void InterleaveStereo(const mixsample_t * MPT_RESTRICT inputL, const mixsample_t * MPT_RESTRICT inputR, mixsample_t * MPT_RESTRICT output, size_t numSamples)
|
||||
{
|
||||
while(numSamples--)
|
||||
{
|
||||
*(output++) = *(inputL++);
|
||||
*(output++) = *(inputR++);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DeinterleaveStereo(const mixsample_t * MPT_RESTRICT input, mixsample_t * MPT_RESTRICT outputL, mixsample_t * MPT_RESTRICT outputR, size_t numSamples)
|
||||
{
|
||||
while(numSamples--)
|
||||
{
|
||||
*(outputL++) = *(input++);
|
||||
*(outputR++) = *(input++);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
OPENMPT_NAMESPACE_END
|
Loading…
Add table
Add a link
Reference in a new issue