blob: 9a9c4cc8be76d96028c88bdbac64b474444c6650 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <stdint.h>
#include <atomic>
#ifndef SERVICES_MEDIA_AUDIO_GAIN_H_
#define SERVICES_MEDIA_AUDIO_GAIN_H_
namespace mojo {
namespace media {
namespace audio {
// A small class used to hold the representation of a factor used for software
// scaling of audio in the mixer pipeline.
class Gain {
public:
// Amplitude scale factors are currently expressed as 4.28 fixed point
// integers stores in unsigned 32 bit integers.
using AScale = uint32_t;
// constructor
Gain();
// Audio gains for tracks and outputs are expressed as floating point in
// decibels. Track and output gains are combined and the stored in the track
// to output link as a 4.28 fixed point amplitude scale factor.
static constexpr unsigned int FRACTIONAL_BITS = 28;
static constexpr AScale UNITY = (static_cast<AScale>(1u) << FRACTIONAL_BITS);
// Set the internal value of the amplitude scaler based on the dB value
// passed. With a 4.28 fixed point internal amplitude scalar, legal values
// are on the range from [-inf, 24.0]
void Set(float db_gain);
// Force the internal amplitude scaler to represent infinite dB down.
void ForceMute() { amplitude_scale_.store(0); }
// Accessor for the current value of the amplitude scaler.
AScale amplitude_scale() const { return amplitude_scale_.load(); }
// Helper function which gives the value of the mute threshold for an
// amplitude scale value for a sample with a given resolution.
//
// @param bit_count The number of non-sign bits for the signed integer
// representation of the sample to be scaled. For example, the bit count used
// to compute the mute threshold when scaling 16 bit signed integers is 15.
//
// @return The value at which the amplitude scaler is guaranteed to drive all
// samples to a value of 0 (meaning that you are wasting compute cycles
// attempting to scale anything). For example, when scaling 16 bit signed
// integers, if amplitude_scale() <= MuteThreshold(15), then all scaled values
// are going to end up as 0, so there is no point in performing the fixed
// point multiply.
static constexpr AScale MuteThreshold(unsigned int bit_count) {
return (static_cast<AScale>(1u) << (FRACTIONAL_BITS - bit_count)) - 1;
}
private:
std::atomic<AScale> amplitude_scale_;
};
} // namespace audio
} // namespace media
} // namespace mojo
#endif // SERVICES_MEDIA_AUDIO_GAIN_H_