pcm/Normalizer: no in-place editing, separate src/dest parameters
This eliminates the memcpy() call from NormalizeFilter::FilterPCM().
This commit is contained in:
parent
8ea9b89321
commit
d7f2d90fd3
|
@ -8,8 +8,7 @@
|
||||||
#include "pcm/Buffer.hxx"
|
#include "pcm/Buffer.hxx"
|
||||||
#include "pcm/AudioFormat.hxx"
|
#include "pcm/AudioFormat.hxx"
|
||||||
#include "pcm/Normalizer.hxx"
|
#include "pcm/Normalizer.hxx"
|
||||||
|
#include "util/SpanCast.hxx"
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
class NormalizeFilter final : public Filter {
|
class NormalizeFilter final : public Filter {
|
||||||
PcmNormalizer normalizer;
|
PcmNormalizer normalizer;
|
||||||
|
@ -49,13 +48,13 @@ PreparedNormalizeFilter::Open(AudioFormat &audio_format)
|
||||||
}
|
}
|
||||||
|
|
||||||
std::span<const std::byte>
|
std::span<const std::byte>
|
||||||
NormalizeFilter::FilterPCM(std::span<const std::byte> src)
|
NormalizeFilter::FilterPCM(std::span<const std::byte> _src)
|
||||||
{
|
{
|
||||||
auto *dest = (int16_t *)buffer.Get(src.size());
|
const auto src = FromBytesStrict<const int16_t>(_src);
|
||||||
memcpy(dest, src.data(), src.size());
|
auto *dest = (int16_t *)buffer.GetT<int16_t>(src.size());
|
||||||
|
|
||||||
normalizer.ProcessS16({dest, src.size() / 2});
|
normalizer.ProcessS16(dest, src);
|
||||||
return { (const std::byte *)dest, src.size() };
|
return std::as_bytes(std::span{dest, src.size()});
|
||||||
}
|
}
|
||||||
|
|
||||||
const FilterPlugin normalize_filter_plugin = {
|
const FilterPlugin normalize_filter_plugin = {
|
||||||
|
|
|
@ -6,9 +6,11 @@
|
||||||
#include "Clamp.hxx"
|
#include "Clamp.hxx"
|
||||||
#include "SampleFormat.hxx"
|
#include "SampleFormat.hxx"
|
||||||
#include "Traits.hxx"
|
#include "Traits.hxx"
|
||||||
|
#include "util/Compiler.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
PcmNormalizer::ProcessS16(const std::span<int16_t> audio) noexcept
|
PcmNormalizer::ProcessS16(int16_t *gcc_restrict dest,
|
||||||
|
const std::span<const int16_t> src) noexcept
|
||||||
{
|
{
|
||||||
constexpr SampleFormat format = SampleFormat::S16;
|
constexpr SampleFormat format = SampleFormat::S16;
|
||||||
using Traits = SampleTraits<format>;
|
using Traits = SampleTraits<format>;
|
||||||
|
@ -16,8 +18,8 @@ PcmNormalizer::ProcessS16(const std::span<int16_t> audio) noexcept
|
||||||
const int slot = (pos + 1) % bufsz;
|
const int slot = (pos + 1) % bufsz;
|
||||||
|
|
||||||
int peakVal = 1, peakPos = 0;
|
int peakVal = 1, peakPos = 0;
|
||||||
for (std::size_t i = 0; i < audio.size(); i++) {
|
for (std::size_t i = 0; i < src.size(); i++) {
|
||||||
int val = audio[i];
|
int val = src[i];
|
||||||
if (val < 0)
|
if (val < 0)
|
||||||
val = -val;
|
val = -val;
|
||||||
if (val > peakVal)
|
if (val > peakVal)
|
||||||
|
@ -52,7 +54,7 @@ PcmNormalizer::ProcessS16(const std::span<int16_t> audio) noexcept
|
||||||
newGain = 1 << 10;
|
newGain = 1 << 10;
|
||||||
|
|
||||||
//! Make sure the adjusted gain won't cause clipping
|
//! Make sure the adjusted gain won't cause clipping
|
||||||
std::size_t ramp = audio.size();
|
std::size_t ramp = src.size();
|
||||||
if ((peakVal*newGain >> 10) > Traits::MAX)
|
if ((peakVal*newGain >> 10) > Traits::MAX)
|
||||||
{
|
{
|
||||||
newGain = (Traits::MAX << 10)/peakVal;
|
newGain = (Traits::MAX << 10)/peakVal;
|
||||||
|
@ -69,9 +71,9 @@ PcmNormalizer::ProcessS16(const std::span<int16_t> audio) noexcept
|
||||||
curGain = 1 << 10;
|
curGain = 1 << 10;
|
||||||
const int delta = (newGain - curGain) / (int)ramp;
|
const int delta = (newGain - curGain) / (int)ramp;
|
||||||
|
|
||||||
for (std::size_t i = 0; i < audio.size(); i++) {
|
for (std::size_t i = 0; i < src.size(); i++) {
|
||||||
//! Amplify the sample
|
//! Amplify the sample
|
||||||
audio[i] = PcmClamp<format>(audio[i] * curGain >> 10);
|
*dest++ = PcmClamp<format>(src[i] * curGain >> 10);
|
||||||
|
|
||||||
//! Adjust the gain
|
//! Adjust the gain
|
||||||
if (i < ramp)
|
if (i < ramp)
|
||||||
|
|
|
@ -41,7 +41,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Process 16-bit signed data
|
//! Process 16-bit signed data
|
||||||
void ProcessS16(std::span<int16_t> audio) noexcept;
|
void ProcessS16(int16_t *dest, std::span<const int16_t> src) noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! TODO: Compressor_Process_int32, Compressor_Process_float, others as needed
|
//! TODO: Compressor_Process_int32, Compressor_Process_float, others as needed
|
||||||
|
|
|
@ -37,8 +37,9 @@ try {
|
||||||
static std::byte buffer[4096];
|
static std::byte buffer[4096];
|
||||||
ssize_t nbytes;
|
ssize_t nbytes;
|
||||||
while ((nbytes = read(0, buffer, sizeof(buffer))) > 0) {
|
while ((nbytes = read(0, buffer, sizeof(buffer))) > 0) {
|
||||||
normalizer.ProcessS16(FromBytesStrict<int16_t>(std::span{buffer}.first(nbytes)));
|
static int16_t dest[2048];
|
||||||
[[maybe_unused]] ssize_t ignored = write(1, buffer, nbytes);
|
normalizer.ProcessS16(dest, FromBytesStrict<const int16_t>(std::span{buffer}.first(nbytes)));
|
||||||
|
[[maybe_unused]] ssize_t ignored = write(1, dest, nbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
Loading…
Reference in New Issue