summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibAudio/Buffer.cpp
diff options
context:
space:
mode:
authorkleines Filmröllchen <malu.bertsch@gmail.com>2021-08-17 00:44:42 +0200
committerAndreas Kling <kling@serenityos.org>2021-08-18 18:16:48 +0200
commitd7ca60b998ebb0b1fb8aa418a3a6cd25609775f0 (patch)
tree1d40eda276d58ffcbe1ac67d06eb322bf48073be /Userland/Libraries/LibAudio/Buffer.cpp
parent6c9343e262abe5a72f8b2f0d71590c627a7eb622 (diff)
downloadserenity-d7ca60b998ebb0b1fb8aa418a3a6cd25609775f0.zip
LibAudio: Resample with integer ratios instead of floats
Floating-point ratios are inherently imprecise, and can lead to unpredictable or nondeterministic behavior when resampling and expecting a certain number of resulting samples. Therefore, the resampler now uses integer ratios, with almost identical but fully predictable behavior. This also introduces the reset() function that the FLAC loader will use in the future.
Diffstat (limited to 'Userland/Libraries/LibAudio/Buffer.cpp')
-rw-r--r--Userland/Libraries/LibAudio/Buffer.cpp29
1 files changed, 21 insertions, 8 deletions
diff --git a/Userland/Libraries/LibAudio/Buffer.cpp b/Userland/Libraries/LibAudio/Buffer.cpp
index efe6945a5f..1039f5bb3f 100644
--- a/Userland/Libraries/LibAudio/Buffer.cpp
+++ b/Userland/Libraries/LibAudio/Buffer.cpp
@@ -8,6 +8,7 @@
#include "Buffer.h"
#include <AK/Atomic.h>
#include <AK/Debug.h>
+#include <AK/StdLibExtras.h>
#include <AK/String.h>
namespace Audio {
@@ -167,18 +168,19 @@ RefPtr<Buffer> Buffer::from_pcm_stream(InputMemoryStream& stream, ResampleHelper
}
template<typename SampleType>
-ResampleHelper<SampleType>::ResampleHelper(double source, double target)
- : m_ratio(source / target)
+ResampleHelper<SampleType>::ResampleHelper(u32 source, u32 target)
+ : m_source(source)
+ , m_target(target)
{
}
-template ResampleHelper<i32>::ResampleHelper(double, double);
-template ResampleHelper<double>::ResampleHelper(double, double);
+template ResampleHelper<i32>::ResampleHelper(u32, u32);
+template ResampleHelper<double>::ResampleHelper(u32, u32);
template<typename SampleType>
Vector<SampleType> ResampleHelper<SampleType>::resample(Vector<SampleType> to_resample)
{
Vector<SampleType> resampled;
- resampled.ensure_capacity(to_resample.size() * m_ratio);
+ resampled.ensure_capacity(to_resample.size() * ceil_div(m_source, m_target));
for (auto sample : to_resample) {
process_sample(sample, sample);
@@ -196,7 +198,7 @@ void ResampleHelper<SampleType>::process_sample(SampleType sample_l, SampleType
{
m_last_sample_l = sample_l;
m_last_sample_r = sample_r;
- m_current_ratio += 1;
+ m_current_ratio += m_target;
}
template void ResampleHelper<i32>::process_sample(i32, i32);
template void ResampleHelper<double>::process_sample(double, double);
@@ -204,8 +206,8 @@ template void ResampleHelper<double>::process_sample(double, double);
template<typename SampleType>
bool ResampleHelper<SampleType>::read_sample(SampleType& next_l, SampleType& next_r)
{
- if (m_current_ratio > 0) {
- m_current_ratio -= m_ratio;
+ if (m_current_ratio >= m_source) {
+ m_current_ratio -= m_source;
next_l = m_last_sample_l;
next_r = m_last_sample_r;
return true;
@@ -216,4 +218,15 @@ bool ResampleHelper<SampleType>::read_sample(SampleType& next_l, SampleType& nex
template bool ResampleHelper<i32>::read_sample(i32&, i32&);
template bool ResampleHelper<double>::read_sample(double&, double&);
+template<typename SampleType>
+void ResampleHelper<SampleType>::reset()
+{
+ m_current_ratio = 0;
+ m_last_sample_l = {};
+ m_last_sample_r = {};
+}
+
+template void ResampleHelper<i32>::reset();
+template void ResampleHelper<double>::reset();
+
}