mirror of https://github.com/AxioDL/boo.git
Not clamping float audio now; better mix quality
This commit is contained in:
parent
e62e8952b5
commit
7410e17179
|
@ -119,7 +119,7 @@ float* AudioMatrixMono::mixMonoSampleData(const AudioVoiceEngineMixInfo& info,
|
||||||
AudioChannel ch = chmap.m_channels[c];
|
AudioChannel ch = chmap.m_channels[c];
|
||||||
if (ch != AudioChannel::Unknown)
|
if (ch != AudioChannel::Unknown)
|
||||||
{
|
{
|
||||||
*dataOut = ClampFlt(*dataOut + *dataIn * (m_coefs.v[int(ch)] * t + m_oldCoefs.v[int(ch)] * omt));
|
*dataOut = *dataOut + *dataIn * (m_coefs.v[int(ch)] * t + m_oldCoefs.v[int(ch)] * omt);
|
||||||
++dataOut;
|
++dataOut;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ float* AudioMatrixMono::mixMonoSampleData(const AudioVoiceEngineMixInfo& info,
|
||||||
AudioChannel ch = chmap.m_channels[c];
|
AudioChannel ch = chmap.m_channels[c];
|
||||||
if (ch != AudioChannel::Unknown)
|
if (ch != AudioChannel::Unknown)
|
||||||
{
|
{
|
||||||
*dataOut = ClampFlt(*dataOut + *dataIn * m_coefs.v[int(ch)]);
|
*dataOut = *dataOut + *dataIn * m_coefs.v[int(ch)];
|
||||||
++dataOut;
|
++dataOut;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -265,9 +265,9 @@ float* AudioMatrixStereo::mixStereoSampleData(const AudioVoiceEngineMixInfo& inf
|
||||||
AudioChannel ch = chmap.m_channels[c];
|
AudioChannel ch = chmap.m_channels[c];
|
||||||
if (ch != AudioChannel::Unknown)
|
if (ch != AudioChannel::Unknown)
|
||||||
{
|
{
|
||||||
*dataOut = ClampFlt(*dataOut +
|
*dataOut = *dataOut +
|
||||||
*dataIn * (m_coefs.v[int(ch)][0] * t + m_oldCoefs.v[int(ch)][0] * omt) +
|
*dataIn * (m_coefs.v[int(ch)][0] * t + m_oldCoefs.v[int(ch)][0] * omt) +
|
||||||
*dataIn * (m_coefs.v[int(ch)][1] * t + m_oldCoefs.v[int(ch)][1] * omt));
|
*dataIn * (m_coefs.v[int(ch)][1] * t + m_oldCoefs.v[int(ch)][1] * omt);
|
||||||
++dataOut;
|
++dataOut;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -281,9 +281,9 @@ float* AudioMatrixStereo::mixStereoSampleData(const AudioVoiceEngineMixInfo& inf
|
||||||
AudioChannel ch = chmap.m_channels[c];
|
AudioChannel ch = chmap.m_channels[c];
|
||||||
if (ch != AudioChannel::Unknown)
|
if (ch != AudioChannel::Unknown)
|
||||||
{
|
{
|
||||||
*dataOut = ClampFlt(*dataOut +
|
*dataOut = *dataOut +
|
||||||
dataIn[0] * m_coefs.v[int(ch)][0] +
|
dataIn[0] * m_coefs.v[int(ch)][0] +
|
||||||
dataIn[1] * m_coefs.v[int(ch)][1]);
|
dataIn[1] * m_coefs.v[int(ch)][1];
|
||||||
++dataOut;
|
++dataOut;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,15 +32,6 @@ static inline int32_t Clamp32(float in)
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float ClampFlt(float in)
|
|
||||||
{
|
|
||||||
if (in < -1.f)
|
|
||||||
return -1.f;
|
|
||||||
else if (in > 1.f)
|
|
||||||
return 1.f;
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
class AudioMatrixMono
|
class AudioMatrixMono
|
||||||
{
|
{
|
||||||
union Coefs
|
union Coefs
|
||||||
|
|
|
@ -320,7 +320,7 @@ float* AudioMatrixMono::mixMonoSampleData(const AudioVoiceEngineMixInfo& info,
|
||||||
samps.q = _mm_shuffle_ps(samps.q, samps.q, _MM_SHUFFLE(1, 0, 1, 0));
|
samps.q = _mm_shuffle_ps(samps.q, samps.q, _MM_SHUFFLE(1, 0, 1, 0));
|
||||||
|
|
||||||
__m128 pre = _mm_add_ps(_mm_loadu_ps(dataOut), _mm_mul_ps(coefs.q, samps.q));
|
__m128 pre = _mm_add_ps(_mm_loadu_ps(dataOut), _mm_mul_ps(coefs.q, samps.q));
|
||||||
_mm_storeu_ps(dataOut, _mm_min_ps(_mm_max_ps(pre, Min32Vec.q), Max32Vec.q));
|
_mm_storeu_ps(dataOut, pre);
|
||||||
|
|
||||||
dataOut += 4;
|
dataOut += 4;
|
||||||
++s;
|
++s;
|
||||||
|
@ -334,7 +334,7 @@ float* AudioMatrixMono::mixMonoSampleData(const AudioVoiceEngineMixInfo& info,
|
||||||
AudioChannel ch = chmap.m_channels[c];
|
AudioChannel ch = chmap.m_channels[c];
|
||||||
if (ch != AudioChannel::Unknown)
|
if (ch != AudioChannel::Unknown)
|
||||||
{
|
{
|
||||||
*dataOut = Clamp32(*dataOut + *dataIn * (m_coefs.v[int(ch)] * t + m_oldCoefs.v[int(ch)] * omt));
|
*dataOut = *dataOut + *dataIn * (m_coefs.v[int(ch)] * t + m_oldCoefs.v[int(ch)] * omt);
|
||||||
++dataOut;
|
++dataOut;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -356,7 +356,7 @@ float* AudioMatrixMono::mixMonoSampleData(const AudioVoiceEngineMixInfo& info,
|
||||||
samps.q = _mm_shuffle_ps(samps.q, samps.q, _MM_SHUFFLE(1, 0, 1, 0));
|
samps.q = _mm_shuffle_ps(samps.q, samps.q, _MM_SHUFFLE(1, 0, 1, 0));
|
||||||
|
|
||||||
__m128 pre = _mm_add_ps(_mm_loadu_ps(dataOut), _mm_mul_ps(coefs.q, samps.q));
|
__m128 pre = _mm_add_ps(_mm_loadu_ps(dataOut), _mm_mul_ps(coefs.q, samps.q));
|
||||||
_mm_storeu_ps(dataOut, _mm_min_ps(_mm_max_ps(pre, Min32Vec.q), Max32Vec.q));
|
_mm_storeu_ps(dataOut, pre);
|
||||||
|
|
||||||
dataOut += 4;
|
dataOut += 4;
|
||||||
++s;
|
++s;
|
||||||
|
@ -370,7 +370,7 @@ float* AudioMatrixMono::mixMonoSampleData(const AudioVoiceEngineMixInfo& info,
|
||||||
AudioChannel ch = chmap.m_channels[c];
|
AudioChannel ch = chmap.m_channels[c];
|
||||||
if (ch != AudioChannel::Unknown)
|
if (ch != AudioChannel::Unknown)
|
||||||
{
|
{
|
||||||
*dataOut = Clamp32(*dataOut + *dataIn * m_coefs.v[int(ch)]);
|
*dataOut = *dataOut + *dataIn * m_coefs.v[int(ch)];
|
||||||
++dataOut;
|
++dataOut;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -508,9 +508,9 @@ float* AudioMatrixStereo::mixStereoSampleData(const AudioVoiceEngineMixInfo& inf
|
||||||
AudioChannel ch = chmap.m_channels[c];
|
AudioChannel ch = chmap.m_channels[c];
|
||||||
if (ch != AudioChannel::Unknown)
|
if (ch != AudioChannel::Unknown)
|
||||||
{
|
{
|
||||||
*dataOut = ClampFlt(*dataOut +
|
*dataOut = *dataOut +
|
||||||
*dataIn * (m_coefs.v[int(ch)][0] * t + m_oldCoefs.v[int(ch)][0] * omt) +
|
*dataIn * (m_coefs.v[int(ch)][0] * t + m_oldCoefs.v[int(ch)][0] * omt) +
|
||||||
*dataIn * (m_coefs.v[int(ch)][1] * t + m_oldCoefs.v[int(ch)][1] * omt));
|
*dataIn * (m_coefs.v[int(ch)][1] * t + m_oldCoefs.v[int(ch)][1] * omt);
|
||||||
++dataOut;
|
++dataOut;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -524,9 +524,9 @@ float* AudioMatrixStereo::mixStereoSampleData(const AudioVoiceEngineMixInfo& inf
|
||||||
AudioChannel ch = chmap.m_channels[c];
|
AudioChannel ch = chmap.m_channels[c];
|
||||||
if (ch != AudioChannel::Unknown)
|
if (ch != AudioChannel::Unknown)
|
||||||
{
|
{
|
||||||
*dataOut = ClampFlt(*dataOut +
|
*dataOut = *dataOut +
|
||||||
dataIn[0] * m_coefs.v[int(ch)][0] +
|
dataIn[0] * m_coefs.v[int(ch)][0] +
|
||||||
dataIn[1] * m_coefs.v[int(ch)][1]);
|
dataIn[1] * m_coefs.v[int(ch)][1];
|
||||||
++dataOut;
|
++dataOut;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ void AudioSubmix::_pumpAndMixVoices(size_t frames, float* dataOut, float* mainOu
|
||||||
for (size_t f=0 ; f<frames ; ++f)
|
for (size_t f=0 ; f<frames ; ++f)
|
||||||
for (size_t c=0 ; c<info.m_channelMap.m_channelCount ; ++c)
|
for (size_t c=0 ; c<info.m_channelMap.m_channelCount ; ++c)
|
||||||
{
|
{
|
||||||
*dataOut = ClampFlt(*dataOut + *it++ * m_gains[c]);
|
*dataOut = *dataOut + *it++ * m_gains[c];
|
||||||
++dataOut;
|
++dataOut;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
struct AudioUnitVoiceEngine;
|
struct AudioUnitVoiceEngine;
|
||||||
|
struct VSTVoiceEngine;
|
||||||
|
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
|
@ -18,6 +19,7 @@ class AudioSubmix : public IAudioSubmix, public IAudioMix
|
||||||
friend class BaseAudioVoiceEngine;
|
friend class BaseAudioVoiceEngine;
|
||||||
friend struct WASAPIAudioVoiceEngine;
|
friend struct WASAPIAudioVoiceEngine;
|
||||||
friend struct ::AudioUnitVoiceEngine;
|
friend struct ::AudioUnitVoiceEngine;
|
||||||
|
friend struct ::VSTVoiceEngine;
|
||||||
|
|
||||||
/* Mixer-engine relationships */
|
/* Mixer-engine relationships */
|
||||||
BaseAudioVoiceEngine& m_root;
|
BaseAudioVoiceEngine& m_root;
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "AudioMatrix.hpp"
|
#include "AudioMatrix.hpp"
|
||||||
|
|
||||||
struct AudioUnitVoiceEngine;
|
struct AudioUnitVoiceEngine;
|
||||||
|
struct VSTVoiceEngine;
|
||||||
|
|
||||||
namespace boo
|
namespace boo
|
||||||
{
|
{
|
||||||
|
@ -20,6 +21,7 @@ class AudioVoice : public IAudioVoice
|
||||||
friend class AudioSubmix;
|
friend class AudioSubmix;
|
||||||
friend struct WASAPIAudioVoiceEngine;
|
friend struct WASAPIAudioVoiceEngine;
|
||||||
friend struct ::AudioUnitVoiceEngine;
|
friend struct ::AudioUnitVoiceEngine;
|
||||||
|
friend struct ::VSTVoiceEngine;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* Mixer-engine relationships */
|
/* Mixer-engine relationships */
|
||||||
|
|
|
@ -451,7 +451,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MIDIReceiveProc(HMIDIIN hMidiIn,
|
static void CALLBACK MIDIReceiveProc(HMIDIIN hMidiIn,
|
||||||
UINT wMsg,
|
UINT wMsg,
|
||||||
IMIDIReceiver* dwInstance,
|
IMIDIReceiver* dwInstance,
|
||||||
DWORD_PTR dwParam1,
|
DWORD_PTR dwParam1,
|
||||||
|
@ -461,7 +461,7 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine
|
||||||
{
|
{
|
||||||
uint8_t (&ptr)[3] = reinterpret_cast<uint8_t(&)[3]>(dwParam1);
|
uint8_t (&ptr)[3] = reinterpret_cast<uint8_t(&)[3]>(dwParam1);
|
||||||
std::vector<uint8_t> bytes(std::cbegin(ptr), std::cend(ptr));
|
std::vector<uint8_t> bytes(std::cbegin(ptr), std::cend(ptr));
|
||||||
dwInstance->m_receiver(std::move(bytes));
|
dwInstance->m_receiver(std::move(bytes), dwParam2 / 1000.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -685,6 +685,8 @@ struct WASAPIAudioVoiceEngine : BaseAudioVoiceEngine
|
||||||
static_cast<MIDIInOut&>(*ret).prepare();
|
static_cast<MIDIInOut&>(*ret).prepare();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool useMIDILock() const {return true;}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<IAudioVoiceEngine> NewAudioVoiceEngine()
|
std::unique_ptr<IAudioVoiceEngine> NewAudioVoiceEngine()
|
||||||
|
|
Loading…
Reference in New Issue