Skip to content

Commit 97bd8ea

Browse files
Merge pull request #31088 from RomanPudashkin/mixer_volume_meter
Mixer: use Peak dB instead of RMS dB
2 parents f7819a0 + 42ebd45 commit 97bd8ea

File tree

7 files changed

+39
-61
lines changed

7 files changed

+39
-61
lines changed

src/framework/audio/common/audiotypes.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -364,13 +364,11 @@ struct AudioParams {
364364
};
365365

366366
struct AudioSignalVal {
367-
float amplitude = 0.f;
368367
volume_dbfs_t pressure = 0.f;
369368

370369
inline bool operator ==(const AudioSignalVal& other) const
371370
{
372-
return muse::is_equal(amplitude, other.amplitude)
373-
&& pressure == other.pressure;
371+
return pressure == other.pressure;
374372
}
375373
};
376374

@@ -379,9 +377,9 @@ using AudioSignalChanges = async::Channel<AudioSignalValuesMap>;
379377

380378
static constexpr volume_dbfs_t MINIMUM_OPERABLE_DBFS_LEVEL = volume_dbfs_t::make(-100.f);
381379
struct AudioSignalsNotifier {
382-
void updateSignalValues(const audioch_t audioChNumber, const float newAmplitude)
380+
void updateSignalValues(const audioch_t audioChNumber, const float newPeak)
383381
{
384-
volume_dbfs_t newPressure = (newAmplitude > 0.f) ? volume_dbfs_t(muse::linear_to_db(newAmplitude)) : MINIMUM_OPERABLE_DBFS_LEVEL;
382+
volume_dbfs_t newPressure = (newPeak > 0.f) ? volume_dbfs_t(muse::linear_to_db(newPeak)) : MINIMUM_OPERABLE_DBFS_LEVEL;
385383
newPressure = std::max(newPressure, MINIMUM_OPERABLE_DBFS_LEVEL);
386384

387385
AudioSignalVal& signalVal = m_signalValuesMap[audioChNumber];
@@ -394,9 +392,7 @@ struct AudioSignalsNotifier {
394392
return;
395393
}
396394

397-
signalVal.amplitude = newAmplitude;
398395
signalVal.pressure = newPressure;
399-
400396
m_needNotifyAboutChanges = true;
401397
}
402398

src/framework/audio/common/rpc/rpcpacker.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,12 +271,12 @@ inline void unpack_custom(muse::msgpack::UnPacker& p, muse::audio::SoundTrackFor
271271

272272
inline void pack_custom(muse::msgpack::Packer& p, const muse::audio::AudioSignalVal& value)
273273
{
274-
p.process(value.amplitude, value.pressure);
274+
p.process(value.pressure);
275275
}
276276

277277
inline void unpack_custom(muse::msgpack::UnPacker& p, muse::audio::AudioSignalVal& value)
278278
{
279-
p.process(value.amplitude, value.pressure);
279+
p.process(value.pressure);
280280
}
281281

282282
inline void pack_custom(muse::msgpack::Packer& p, const muse::audio::InputProcessingProgress::ChunkInfo& value)

src/framework/audio/engine/internal/mixer.cpp

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,6 @@ void Mixer::setOutputSpec(const OutputSpec& spec)
182182

183183
m_outputSpec = spec;
184184

185-
m_limiter = std::make_unique<dsp::Limiter>(spec.sampleRate);
186-
187185
AbstractAudioSource::setOutputSpec(spec);
188186

189187
for (auto& channel : m_trackChannels) {
@@ -567,37 +565,34 @@ void Mixer::completeOutput(float* buffer, samples_t samplesPerChannel)
567565
return;
568566
}
569567

570-
float totalSquaredSum = 0.f;
571-
float volume = muse::db_to_linear(m_masterParams.volume);
568+
const float volume = muse::db_to_linear(m_masterParams.volume);
569+
float globalPeak = 0.f;
572570

573571
for (audioch_t audioChNum = 0; audioChNum < m_outputSpec.audioChannelCount; ++audioChNum) {
574-
float singleChannelSquaredSum = 0.f;
575-
gain_t totalGain = dsp::balanceGain(m_masterParams.balance, audioChNum) * volume;
572+
const gain_t totalGain = dsp::balanceGain(m_masterParams.balance, audioChNum) * volume;
573+
float peak = 0.f;
576574

577575
for (samples_t s = 0; s < samplesPerChannel; ++s) {
578-
int idx = s * m_outputSpec.audioChannelCount + audioChNum;
576+
const size_t idx = s * m_outputSpec.audioChannelCount + audioChNum;
577+
const float resultSample = buffer[idx] * totalGain;
578+
const float absSample = std::fabs(resultSample);
579579

580-
float resultSample = buffer[idx] * totalGain;
581580
buffer[idx] = resultSample;
582581

583-
float squaredSample = resultSample * resultSample;
584-
totalSquaredSum += squaredSample;
585-
singleChannelSquaredSum += squaredSample;
582+
if (absSample > peak) {
583+
peak = absSample;
584+
}
586585
}
587586

588-
float rms = dsp::samplesRootMeanSquare(singleChannelSquaredSum, samplesPerChannel);
589-
m_audioSignalNotifier.updateSignalValues(audioChNum, rms);
590-
}
591-
592-
m_isSilence = RealIsNull(totalSquaredSum);
593-
m_audioSignalNotifier.notifyAboutChanges();
587+
m_audioSignalNotifier.updateSignalValues(audioChNum, peak);
594588

595-
if (!m_limiter->isActive()) {
596-
return;
589+
if (peak > globalPeak) {
590+
globalPeak = peak;
591+
}
597592
}
598593

599-
float totalRms = dsp::samplesRootMeanSquare(totalSquaredSum, samplesPerChannel * m_outputSpec.audioChannelCount);
600-
m_limiter->process(totalRms, buffer, m_outputSpec.audioChannelCount, samplesPerChannel);
594+
m_isSilence = RealIsNull(globalPeak);
595+
m_audioSignalNotifier.notifyAboutChanges();
601596
}
602597

603598
void Mixer::notifyNoAudioSignal()

src/framework/audio/engine/internal/mixer.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
#include "../iclock.h"
3535
#include "../ifxresolver.h"
3636

37-
#include "dsp/limiter.h"
3837
#include "mixerchannel.h"
3938
#include "igetplaybackposition.h"
4039

@@ -115,8 +114,6 @@ class Mixer : public AbstractAudioSource, public IGetPlaybackPosition, public In
115114

116115
std::vector<AuxChannelInfo> m_auxChannelInfoList;
117116

118-
dsp::LimiterPtr m_limiter = nullptr;
119-
120117
std::set<IClockPtr> m_clocks;
121118

122119
mutable AudioSignalsNotifier m_audioSignalNotifier;

src/framework/audio/engine/internal/mixerchannel.cpp

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ MixerChannel::MixerChannel(const TrackId trackId, const OutputSpec& outputSpec,
4141
: Injectable(iocCtx), m_trackId(trackId),
4242
m_outputSpec(outputSpec),
4343
m_audioSource(std::move(source)),
44-
m_getPlaybackPosition(getPlaybackPosition),
45-
m_compressor(std::make_unique<dsp::Compressor>(outputSpec.sampleRate))
44+
m_getPlaybackPosition(getPlaybackPosition)
4645
{
4746
ONLY_AUDIO_ENGINE_THREAD;
4847
}
@@ -223,39 +222,35 @@ samples_t MixerChannel::process(float* buffer, samples_t samplesPerChannel)
223222

224223
void MixerChannel::completeOutput(float* buffer, unsigned int samplesCount)
225224
{
226-
unsigned int channelsCount = audioChannelsCount();
227-
float volume = muse::db_to_linear(m_params.volume);
228-
float totalSquaredSum = 0.f;
225+
const unsigned int channelsCount = audioChannelsCount();
226+
const float volume = muse::db_to_linear(m_params.volume);
227+
float globalPeak = 0.f;
229228

230229
for (audioch_t audioChNum = 0; audioChNum < channelsCount; ++audioChNum) {
231-
float singleChannelSquaredSum = 0.f;
232-
233-
gain_t totalGain = dsp::balanceGain(m_params.balance, audioChNum) * volume;
230+
const gain_t totalGain = dsp::balanceGain(m_params.balance, audioChNum) * volume;
231+
float peak = 0.f;
234232

235233
for (unsigned int s = 0; s < samplesCount; ++s) {
236-
int idx = s * channelsCount + audioChNum;
234+
const unsigned int idx = s * channelsCount + audioChNum;
235+
const float resultSample = buffer[idx] * totalGain;
236+
const float absSample = std::fabs(resultSample);
237237

238-
float resultSample = buffer[idx] * totalGain;
239238
buffer[idx] = resultSample;
240239

241-
float squaredSample = resultSample * resultSample;
242-
singleChannelSquaredSum += squaredSample;
243-
totalSquaredSum += squaredSample;
240+
if (absSample > peak) {
241+
peak = absSample;
242+
}
244243
}
245244

246-
float rms = dsp::samplesRootMeanSquare(singleChannelSquaredSum, samplesCount);
247-
m_audioSignalNotifier.updateSignalValues(audioChNum, rms);
248-
}
245+
m_audioSignalNotifier.updateSignalValues(audioChNum, peak);
249246

250-
m_isSilent = RealIsNull(totalSquaredSum);
251-
m_audioSignalNotifier.notifyAboutChanges();
252-
253-
if (!m_compressor->isActive()) {
254-
return;
247+
if (peak > globalPeak) {
248+
globalPeak = peak;
249+
}
255250
}
256251

257-
float totalRms = dsp::samplesRootMeanSquare(totalSquaredSum, samplesCount * channelsCount);
258-
m_compressor->process(totalRms, buffer, channelsCount, samplesCount);
252+
m_isSilent = RealIsNull(globalPeak);
253+
m_audioSignalNotifier.notifyAboutChanges();
259254
}
260255

261256
bool MixerChannel::isSilent() const

src/framework/audio/engine/internal/mixerchannel.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828

2929
#include "../ifxresolver.h"
3030
#include "../ifxprocessor.h"
31-
#include "dsp/compressor.h"
3231
#include "track.h"
3332

3433
namespace muse::audio::engine {
@@ -79,8 +78,6 @@ class MixerChannel : public ITrackAudioOutput, public Injectable, public async::
7978
const IGetPlaybackPosition* m_getPlaybackPosition = nullptr;
8079
std::vector<IFxProcessorPtr> m_fxProcessors = {};
8180

82-
dsp::CompressorPtr m_compressor = nullptr;
83-
8481
bool m_isSilent = true;
8582

8683
async::Notification m_mutedChanged;

src/framework/audio/tests/rpcpacker_tests.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,11 +295,9 @@ TEST_F(Audio_RpcPackerTests, AudioSourceParams)
295295
TEST_F(Audio_RpcPackerTests, AudioSignalVal)
296296
{
297297
AudioSignalVal origin;
298-
origin.amplitude = 0.6f;
299298
origin.pressure = 0.5;
300299

301300
KNOWN_FIELDS(origin,
302-
origin.amplitude,
303301
origin.pressure);
304302

305303
ByteArray data = rpc::RpcPacker::pack(origin);

0 commit comments

Comments
 (0)