Modified: trunk/Source/WebCore/ChangeLog (285022 => 285023)
--- trunk/Source/WebCore/ChangeLog 2021-10-29 09:15:15 UTC (rev 285022)
+++ trunk/Source/WebCore/ChangeLog 2021-10-29 09:50:10 UTC (rev 285023)
@@ -1,5 +1,19 @@
2021-10-29 Youenn Fablet <[email protected]>
+ LocalAudioMediaStreamTrackRendererInternalUnit should clip audio data
+ https://bugs.webkit.org/show_bug.cgi?id=232428
+
+ Reviewed by Eric Carlson.
+
+ When using a bluetooth speaker, unclipped audio data triggers distortion, contrary to built-in speakers.
+ To prevent this, we clip audio data just before rendering for float audio samples.
+
+ Manually tested.
+
+ * platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.cpp:
+
+2021-10-29 Youenn Fablet <[email protected]>
+
AudioMediaStreamTrackRendererUnit::render should handle the case of failing to pull samples from the first source
https://bugs.webkit.org/show_bug.cgi?id=232429
Modified: trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.cpp (285022 => 285023)
--- trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.cpp 2021-10-29 09:15:15 UTC (rev 285022)
+++ trunk/Source/WebCore/platform/mediastream/cocoa/AudioMediaStreamTrackRendererInternalUnit.cpp 2021-10-29 09:50:10 UTC (rev 285023)
@@ -33,6 +33,7 @@
#include "CAAudioStreamDescription.h"
#include "Logging.h"
+#include <Accelerate/Accelerate.h>
#include <pal/spi/cocoa/AudioToolboxSPI.h>
#include <wtf/FastMalloc.h>
#include <wtf/Lock.h>
@@ -235,6 +236,41 @@
m_remoteIOUnit = remoteIOUnit;
}
+static void clipAudioBuffer(float* vector, size_t size)
+{
+ float minimum = -1;
+ float maximum = 1;
+ vDSP_vclip(vector, 1, &minimum, &maximum, vector, 1, size);
+}
+
+static void clipAudioBuffer(double* vector, size_t size)
+{
+ double minimum = -1;
+ double maximum = 1;
+ vDSP_vclipD(vector, 1, &minimum, &maximum, vector, 1, size);
+}
+
+static void clipAudioBufferList(AudioBufferList& list, AudioStreamDescription::PCMFormat format)
+{
+ switch (format) {
+ case AudioStreamDescription::Int16:
+ break;
+ case AudioStreamDescription::Int32:
+ break;
+ case AudioStreamDescription::Float32:
+ for (size_t index = 0; index < list.mNumberBuffers ; ++index)
+ clipAudioBuffer(static_cast<float*>(list.mBuffers[index].mData), list.mBuffers[index].mDataByteSize / sizeof(float));
+ break;
+ case AudioStreamDescription::Float64:
+ for (size_t index = 0; index < list.mNumberBuffers ; ++index)
+ clipAudioBuffer(static_cast<double*>(list.mBuffers[index].mData), list.mBuffers[index].mDataByteSize / sizeof(double));
+ break;
+ case AudioStreamDescription::None:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
OSStatus LocalAudioMediaStreamTrackRendererInternalUnit::render(AudioUnitRenderActionFlags* actionFlags, const AudioTimeStamp* timeStamp, UInt32 sampleCount, AudioBufferList* ioData)
{
auto sampleTime = timeStamp->mSampleTime;
@@ -243,7 +279,10 @@
m_resetCallback();
m_sampleTime = sampleTime < std::numeric_limits<Float64>::max() - sampleCount ? sampleTime : 0;
- return m_renderCallback(sampleCount, *ioData, sampleTime, timeStamp->mHostTime, *actionFlags);
+ auto result = m_renderCallback(sampleCount, *ioData, sampleTime, timeStamp->mHostTime, *actionFlags);
+ // FIXME: We should probably introduce a limiter to limit the amount of clipping.
+ clipAudioBufferList(*ioData, m_outputDescription->format());
+ return result;
}
OSStatus LocalAudioMediaStreamTrackRendererInternalUnit::renderingCallback(void* processor, AudioUnitRenderActionFlags* actionFlags, const AudioTimeStamp* timeStamp, UInt32, UInt32 sampleCount, AudioBufferList* ioData)