-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Copy pathchannelmixer.cpp
98 lines (95 loc) · 4.22 KB
/
channelmixer.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include "engine/channelmixer.h"
#include "engine/effects/engineeffectsmanager.h"
#include "util/sample.h"
#include "util/timer.h"
// static
void ChannelMixer::applyEffectsAndMixChannels(const EngineMixer::GainCalculator& gainCalculator,
const QVarLengthArray<EngineMixer::ChannelInfo*, kPreallocatedChannels>& activeChannels,
QVarLengthArray<EngineMixer::GainCache, kPreallocatedChannels>* channelGainCache,
CSAMPLE* pOutput,
const ChannelHandle& outputHandle,
std::size_t bufferSize,
mixxx::audio::SampleRate sampleRate,
EngineEffectsManager* pEngineEffectsManager) {
// Signal flow overview:
// 1. Clear pOutput buffer
// 2. Calculate gains for each channel
// 3. Pass each channel's calculated gain and input buffer to pEngineEffectsManager, which then:
// A) Copies each channel input buffer to a temporary buffer
// B) Applies gain to the temporary buffer
// C) Processes effects on the temporary buffer
// D) Mixes the temporary buffer into pOutput
// The original channel input buffers are not modified.
SampleUtil::clear(pOutput, bufferSize);
ScopedTimer t(QStringLiteral("EngineMixer::applyEffectsAndMixChannels"));
for (auto* pChannelInfo : activeChannels) {
EngineMixer::GainCache& gainCache = (*channelGainCache)[pChannelInfo->m_index];
CSAMPLE_GAIN oldGain = gainCache.m_gain;
CSAMPLE_GAIN newGain;
bool fadeout = gainCache.m_fadeout ||
(pChannelInfo->m_pChannel &&
!pChannelInfo->m_pChannel->isActive());
if (fadeout) {
newGain = 0;
gainCache.m_fadeout = false;
} else {
newGain = gainCalculator.getGain(pChannelInfo);
}
gainCache.m_gain = newGain;
pEngineEffectsManager->processPostFaderAndMix(pChannelInfo->m_handle,
outputHandle,
pChannelInfo->m_pBuffer.data(),
pOutput,
bufferSize,
sampleRate,
pChannelInfo->m_features,
oldGain,
newGain,
fadeout);
}
}
void ChannelMixer::applyEffectsInPlaceAndMixChannels(
const EngineMixer::GainCalculator& gainCalculator,
const QVarLengthArray<EngineMixer::ChannelInfo*, kPreallocatedChannels>&
activeChannels,
QVarLengthArray<EngineMixer::GainCache, kPreallocatedChannels>*
channelGainCache,
CSAMPLE* pOutput,
const ChannelHandle& outputHandle,
std::size_t bufferSize,
mixxx::audio::SampleRate sampleRate,
EngineEffectsManager* pEngineEffectsManager) {
// Signal flow overview:
// 1. Calculate gains for each channel
// 2. Pass each channel's calculated gain and input buffer to pEngineEffectsManager, which then:
// A) Applies the calculated gain to the channel buffer, modifying the original input buffer
// B) Applies effects to the buffer, modifying the original input buffer
// 4. Mix the channel buffers together to make pOutput, overwriting the pOutput buffer from the last engine callback
ScopedTimer t(QStringLiteral("EngineMixer::applyEffectsInPlaceAndMixChannels"));
SampleUtil::clear(pOutput, bufferSize);
for (auto* pChannelInfo : activeChannels) {
EngineMixer::GainCache& gainCache = (*channelGainCache)[pChannelInfo->m_index];
CSAMPLE_GAIN oldGain = gainCache.m_gain;
CSAMPLE_GAIN newGain;
bool fadeout = gainCache.m_fadeout ||
(pChannelInfo->m_pChannel &&
!pChannelInfo->m_pChannel->isActive());
if (fadeout) {
newGain = 0;
gainCache.m_fadeout = false;
} else {
newGain = gainCalculator.getGain(pChannelInfo);
}
gainCache.m_gain = newGain;
pEngineEffectsManager->processPostFaderInPlace(pChannelInfo->m_handle,
outputHandle,
pChannelInfo->m_pBuffer.data(),
bufferSize,
sampleRate,
pChannelInfo->m_features,
oldGain,
newGain,
fadeout);
SampleUtil::add(pOutput, pChannelInfo->m_pBuffer.data(), bufferSize);
}
}