Title: [268826] trunk/Source/WebCore
Revision
268826
Author
[email protected]
Date
2020-10-21 14:33:05 -0700 (Wed, 21 Oct 2020)

Log Message

Update FFTFrame::realData() / imagData() to return an AudioFloatArray
https://bugs.webkit.org/show_bug.cgi?id=218048

Reviewed by Philippe Normand.

Update FFTFrame::realData() / imagData() to return an AudioFloatArray instead of a float*.
It is risky to expose a float* since the caller has no way to know the actual size of the
array. By returning an AudioFloatArray, the caller can query AudioFloatArray::size() to
know the actual size. Note that it is not safe to assume that the size of these arrays
is FFTFrame::fftSize() because this is not true for ports using GStreamer.

* Modules/webaudio/PeriodicWave.cpp:
(WebCore::PeriodicWave::createBandLimitedTables):
* Modules/webaudio/RealtimeAnalyser.cpp:
(WebCore::RealtimeAnalyser::doFFTAnalysisIfNecessary):
* platform/audio/FFTFrame.cpp:
(WebCore::FFTFrame::interpolateFrequencyComponents):
(WebCore::FFTFrame::scaleFFT):
(WebCore::FFTFrame::multiply):
(WebCore::FFTFrame::extractAverageGroupDelay):
(WebCore::FFTFrame::addConstantGroupDelay):
(WebCore::FFTFrame::print):
* platform/audio/FFTFrame.h:
(WebCore::FFTFrame::realData):
(WebCore::FFTFrame::imagData):
(WebCore::FFTFrame::realData const):
(WebCore::FFTFrame::imagData const):
* platform/audio/FFTFrameStub.cpp:
(WebCore::FFTFrame::realData const): Deleted.
(WebCore::FFTFrame::imagData const): Deleted.
* platform/audio/gstreamer/FFTFrameGStreamer.cpp:
(WebCore::FFTFrame::FFTFrame):
(WebCore::FFTFrame::realData const): Deleted.
(WebCore::FFTFrame::imagData const): Deleted.
* platform/audio/mac/FFTFrameMac.cpp:
(WebCore::FFTFrame::FFTFrame):
(WebCore::FFTFrame::doFFT):
(WebCore::FFTFrame::realData const): Deleted.
(WebCore::FFTFrame::imagData const): Deleted.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (268825 => 268826)


--- trunk/Source/WebCore/ChangeLog	2020-10-21 21:24:06 UTC (rev 268825)
+++ trunk/Source/WebCore/ChangeLog	2020-10-21 21:33:05 UTC (rev 268826)
@@ -1,3 +1,45 @@
+2020-10-21  Chris Dumez  <[email protected]>
+
+        Update FFTFrame::realData() / imagData() to return an AudioFloatArray
+        https://bugs.webkit.org/show_bug.cgi?id=218048
+
+        Reviewed by Philippe Normand.
+
+        Update FFTFrame::realData() / imagData() to return an AudioFloatArray instead of a float*.
+        It is risky to expose a float* since the caller has no way to know the actual size of the
+        array. By returning an AudioFloatArray, the caller can query AudioFloatArray::size() to
+        know the actual size. Note that it is not safe to assume that the size of these arrays
+        is FFTFrame::fftSize() because this is not true for ports using GStreamer.
+
+        * Modules/webaudio/PeriodicWave.cpp:
+        (WebCore::PeriodicWave::createBandLimitedTables):
+        * Modules/webaudio/RealtimeAnalyser.cpp:
+        (WebCore::RealtimeAnalyser::doFFTAnalysisIfNecessary):
+        * platform/audio/FFTFrame.cpp:
+        (WebCore::FFTFrame::interpolateFrequencyComponents):
+        (WebCore::FFTFrame::scaleFFT):
+        (WebCore::FFTFrame::multiply):
+        (WebCore::FFTFrame::extractAverageGroupDelay):
+        (WebCore::FFTFrame::addConstantGroupDelay):
+        (WebCore::FFTFrame::print):
+        * platform/audio/FFTFrame.h:
+        (WebCore::FFTFrame::realData):
+        (WebCore::FFTFrame::imagData):
+        (WebCore::FFTFrame::realData const):
+        (WebCore::FFTFrame::imagData const):
+        * platform/audio/FFTFrameStub.cpp:
+        (WebCore::FFTFrame::realData const): Deleted.
+        (WebCore::FFTFrame::imagData const): Deleted.
+        * platform/audio/gstreamer/FFTFrameGStreamer.cpp:
+        (WebCore::FFTFrame::FFTFrame):
+        (WebCore::FFTFrame::realData const): Deleted.
+        (WebCore::FFTFrame::imagData const): Deleted.
+        * platform/audio/mac/FFTFrameMac.cpp:
+        (WebCore::FFTFrame::FFTFrame):
+        (WebCore::FFTFrame::doFFT):
+        (WebCore::FFTFrame::realData const): Deleted.
+        (WebCore::FFTFrame::imagData const): Deleted.
+
 2020-10-21  Zalan Bujtas  <[email protected]>
 
         [LFC][Integration] Add content dependent vertical line snapping

Modified: trunk/Source/WebCore/Modules/webaudio/PeriodicWave.cpp (268825 => 268826)


--- trunk/Source/WebCore/Modules/webaudio/PeriodicWave.cpp	2020-10-21 21:24:06 UTC (rev 268825)
+++ trunk/Source/WebCore/Modules/webaudio/PeriodicWave.cpp	2020-10-21 21:33:05 UTC (rev 268826)
@@ -196,12 +196,15 @@
     for (unsigned rangeIndex = 0; rangeIndex < m_numberOfRanges; ++rangeIndex) {
         // This FFTFrame is used to cull partials (represented by frequency bins).
         FFTFrame frame(fftSize);
-        float* realP = frame.realData();
-        float* imagP = frame.imagData();
+        auto& realP = frame.realData();
+        auto& imagP = frame.imagData();
 
+        RELEASE_ASSERT(realP.size() >= numberOfComponents);
+        RELEASE_ASSERT(imagP.size() >= numberOfComponents);
+
         // Copy from loaded frequency data and scale.
-        VectorMath::multiplyByScalar(realData, fftSize, realP, numberOfComponents);
-        VectorMath::multiplyByScalar(imagData, -static_cast<float>(fftSize), imagP, numberOfComponents);
+        VectorMath::multiplyByScalar(realData, fftSize, realP.data(), numberOfComponents);
+        VectorMath::multiplyByScalar(imagData, -static_cast<float>(fftSize), imagP.data(), numberOfComponents);
 
         // Find the starting bin where we should start culling.
         // We need to clear out the highest frequencies to band-limit the waveform.

Modified: trunk/Source/WebCore/Modules/webaudio/RealtimeAnalyser.cpp (268825 => 268826)


--- trunk/Source/WebCore/Modules/webaudio/RealtimeAnalyser.cpp	2020-10-21 21:24:06 UTC (rev 268825)
+++ trunk/Source/WebCore/Modules/webaudio/RealtimeAnalyser.cpp	2020-10-21 21:33:05 UTC (rev 268826)
@@ -154,8 +154,8 @@
     // Do the analysis.
     m_analysisFrame->doFFT(tempP);
 
-    float* realP = m_analysisFrame->realData();
-    float* imagP = m_analysisFrame->imagData();
+    auto& realP = m_analysisFrame->realData();
+    auto& imagP = m_analysisFrame->imagData();
 
     // Blow away the packed nyquist component.
     imagP[0] = 0;

Modified: trunk/Source/WebCore/platform/audio/AudioArray.h (268825 => 268826)


--- trunk/Source/WebCore/platform/audio/AudioArray.h	2020-10-21 21:24:06 UTC (rev 268825)
+++ trunk/Source/WebCore/platform/audio/AudioArray.h	2020-10-21 21:33:05 UTC (rev 268826)
@@ -81,7 +81,16 @@
         return data()[i];
     }
 
+    const T& at(size_t i) const
+    {
+        // Note that although it is a size_t, m_size is now guaranteed to be
+        // no greater than max unsigned. This guarantee is enforced in resize().
+        ASSERT_WITH_SECURITY_IMPLICATION(i < size());
+        return data()[i];
+    }
+
     T& operator[](size_t i) { return at(i); }
+    const T& operator[](size_t i) const { return at(i); }
 
     void zero()
     {

Modified: trunk/Source/WebCore/platform/audio/FFTFrame.cpp (268825 => 268826)


--- trunk/Source/WebCore/platform/audio/FFTFrame.cpp	2020-10-21 21:24:06 UTC (rev 268825)
+++ trunk/Source/WebCore/platform/audio/FFTFrame.cpp	2020-10-21 21:33:05 UTC (rev 268826)
@@ -75,13 +75,13 @@
 {
     // FIXME : with some work, this method could be optimized
 
-    float* realP = realData();
-    float* imagP = imagData();
+    auto& realP = realData();
+    auto& imagP = imagData();
 
-    const float* realP1 = frame1.realData();
-    const float* imagP1 = frame1.imagData();
-    const float* realP2 = frame2.realData();
-    const float* imagP2 = frame2.imagData();
+    const auto& realP1 = frame1.realData();
+    const auto& imagP1 = frame1.imagData();
+    const auto& realP2 = frame2.realData();
+    const auto& imagP2 = frame2.imagData();
 
     m_FFTSize = frame1.fftSize();
     m_log2FFTSize = frame1.log2FFTSize();
@@ -175,8 +175,8 @@
 
 void FFTFrame::scaleFFT(float factor)
 {
-    VectorMath::multiplyByScalar(realData(), factor, realData(), fftSize());
-    VectorMath::multiplyByScalar(imagData(), factor, imagData(), fftSize());
+    VectorMath::multiplyByScalar(realData().data(), factor, realData().data(), realData().size());
+    VectorMath::multiplyByScalar(imagData().data(), factor, imagData().data(), realData().size());
 }
 
 void FFTFrame::multiply(const FFTFrame& frame)
@@ -184,17 +184,23 @@
     FFTFrame& frame1 = *this;
     const FFTFrame& frame2 = frame;
 
-    float* realP1 = frame1.realData();
-    float* imagP1 = frame1.imagData();
-    const float* realP2 = frame2.realData();
-    const float* imagP2 = frame2.imagData();
+    auto& realP1 = frame1.realData();
+    auto& imagP1 = frame1.imagData();
+    const auto& realP2 = frame2.realData();
+    const auto& imagP2 = frame2.imagData();
 
     unsigned halfSize = m_FFTSize / 2;
+
+    RELEASE_ASSERT(realP1.size() >= halfSize);
+    RELEASE_ASSERT(imagP1.size() >= halfSize);
+    RELEASE_ASSERT(realP2.size() >= halfSize);
+    RELEASE_ASSERT(imagP2.size() >= halfSize);
+
     float real0 = realP1[0];
     float imag0 = imagP1[0];
 
     // Complex multiply
-    VectorMath::multiplyComplex(realP1, imagP1, realP2, imagP2, realP1, imagP1, halfSize);
+    VectorMath::multiplyComplex(realP1.data(), imagP1.data(), realP2.data(), imagP2.data(), realP1.data(), imagP1.data(), halfSize);
 
     // Multiply the packed DC/nyquist component
     realP1[0] = real0 * realP2[0];
@@ -203,8 +209,8 @@
 
 double FFTFrame::extractAverageGroupDelay()
 {
-    float* realP = realData();
-    float* imagP = imagData();
+    auto& realP = realData();
+    auto& imagP = imagData();
 
     double aveSum = 0.0;
     double weightSum = 0.0;
@@ -254,8 +260,8 @@
 {
     int halfSize = fftSize() / 2;
 
-    float* realP = realData();
-    float* imagP = imagData();
+    auto& realP = realData();
+    auto& imagP = imagData();
 
     const double kSamplePhaseDelay = (2.0 * piDouble) / double(fftSize());
 
@@ -280,8 +286,8 @@
 void FFTFrame::print()
 {
     FFTFrame& frame = *this;
-    float* realP = frame.realData();
-    float* imagP = frame.imagData();
+    auto& realP = frame.realData();
+    auto& imagP = frame.imagData();
     LOG(WebAudio, "**** \n");
     LOG(WebAudio, "DC = %f : nyquist = %f\n", realP[0], imagP[0]);
 

Modified: trunk/Source/WebCore/platform/audio/FFTFrame.h (268825 => 268826)


--- trunk/Source/WebCore/platform/audio/FFTFrame.h	2020-10-21 21:24:06 UTC (rev 268825)
+++ trunk/Source/WebCore/platform/audio/FFTFrame.h	2020-10-21 21:33:05 UTC (rev 268826)
@@ -67,8 +67,10 @@
     void multiply(const FFTFrame& frame); // multiplies ourself with frame : effectively operator*=()
     void scaleFFT(float factor);
 
-    float* realData() const;
-    float* imagData() const;
+    AudioFloatArray& realData() { return m_realData; }
+    AudioFloatArray& imagData() { return m_imagData; }
+    const AudioFloatArray& realData() const { return m_realData; }
+    const AudioFloatArray& imagData() const { return m_imagData; }
 
     static int minFFTSize();
     static int maxFFTSize();
@@ -103,8 +105,6 @@
     FFTSetup m_FFTSetup;
 
     DSPSplitComplex m_frame;
-    AudioFloatArray m_realData;
-    AudioFloatArray m_imagData;
 #endif
 
 #if USE(WEBAUDIO_GSTREAMER)
@@ -111,9 +111,10 @@
     GstFFTF32* m_fft;
     GstFFTF32* m_inverseFft;
     UniqueArray<GstFFTF32Complex> m_complexData;
+#endif // USE(WEBAUDIO_GSTREAMER)
+
     AudioFloatArray m_realData;
     AudioFloatArray m_imagData;
-#endif // USE(WEBAUDIO_GSTREAMER)
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/audio/FFTFrameStub.cpp (268825 => 268826)


--- trunk/Source/WebCore/platform/audio/FFTFrameStub.cpp	2020-10-21 21:24:06 UTC (rev 268825)
+++ trunk/Source/WebCore/platform/audio/FFTFrameStub.cpp	2020-10-21 21:33:05 UTC (rev 268826)
@@ -78,18 +78,6 @@
 {
 }
 
-float* FFTFrame::realData() const
-{
-    ASSERT_NOT_REACHED();
-    return 0;
-}
-
-float* FFTFrame::imagData() const
-{
-    ASSERT_NOT_REACHED();
-    return 0;
-}
-
 } // namespace WebCore
 
 #endif // !OS(DARWIN) && !USE(WEBAUDIO_GSTREAMER)

Modified: trunk/Source/WebCore/platform/audio/gstreamer/FFTFrameGStreamer.cpp (268825 => 268826)


--- trunk/Source/WebCore/platform/audio/gstreamer/FFTFrameGStreamer.cpp	2020-10-21 21:24:06 UTC (rev 268825)
+++ trunk/Source/WebCore/platform/audio/gstreamer/FFTFrameGStreamer.cpp	2020-10-21 21:33:05 UTC (rev 268826)
@@ -79,8 +79,8 @@
     m_inverseFft = gst_fft_f32_new(fftLength, TRUE);
 
     // Copy/setup frame data.
-    memcpy(realData(), frame.realData(), sizeof(float) * unpackedFFTDataSize(m_FFTSize));
-    memcpy(imagData(), frame.imagData(), sizeof(float) * unpackedFFTDataSize(m_FFTSize));
+    memcpy(realData().data(), frame.realData().data(), sizeof(float) * realData().size());
+    memcpy(imagData().data(), frame.imagData().data(), sizeof(float) * imagData().size());
 }
 
 void FFTFrame::initialize()
@@ -128,16 +128,6 @@
     VectorMath::multiplyByScalar(data, 1.0 / m_FFTSize, data, m_FFTSize);
 }
 
-float* FFTFrame::realData() const
-{
-    return const_cast<float*>(m_realData.data());
-}
-
-float* FFTFrame::imagData() const
-{
-    return const_cast<float*>(m_imagData.data());
-}
-
 int FFTFrame::minFFTSize()
 {
     return 1 << kMinFFTPow2Size;

Modified: trunk/Source/WebCore/platform/audio/mac/FFTFrameMac.cpp (268825 => 268826)


--- trunk/Source/WebCore/platform/audio/mac/FFTFrameMac.cpp	2020-10-21 21:24:06 UTC (rev 268825)
+++ trunk/Source/WebCore/platform/audio/mac/FFTFrameMac.cpp	2020-10-21 21:33:05 UTC (rev 268826)
@@ -66,8 +66,6 @@
 
 // Creates a blank/empty frame (interpolate() must later be called)
 FFTFrame::FFTFrame()
-    : m_realData(0)
-    , m_imagData(0)
 {
     // Later will be set to correct values when interpolate() is called
     m_frame.realp = 0;
@@ -90,9 +88,8 @@
     m_frame.imagp = m_imagData.data();
 
     // Copy/setup frame data
-    unsigned nbytes = sizeof(float) * m_FFTSize;
-    memcpy(realData(), frame.m_frame.realp, nbytes);
-    memcpy(imagData(), frame.m_frame.imagp, nbytes);
+    memcpy(realData().data(), frame.m_frame.realp, sizeof(float) * realData().size());
+    memcpy(imagData().data(), frame.m_frame.imagp, sizeof(float) * imagData().size());
 }
 
 FFTFrame::~FFTFrame() = default;
@@ -103,13 +100,16 @@
     vDSP_ctoz(reinterpret_cast<const DSPComplex*>(data), 2, &m_frame, 1, halfSize);
     vDSP_fft_zrip(m_FFTSetup, &m_frame, 1, m_log2FFTSize, FFT_FORWARD);
 
+    RELEASE_ASSERT(realData().size() >= halfSize);
+    RELEASE_ASSERT(imagData().size() >= halfSize);
+
     // To provide the best possible execution speeds, the vDSP library's functions don't always adhere strictly
     // to textbook formulas for Fourier transforms, and must be scaled accordingly.
     // (See https://developer.apple.com/library/archive/documentation/Performance/Conceptual/vDSP_Programming_Guide/UsingFourierTransforms/UsingFourierTransforms.html#//apple_ref/doc/uid/TP40005147-CH3-SW5)
     // In the case of a Real forward Transform like above: RFimp = RFmath * 2 so we need to divide the output
     // by 2 to get the correct value.
-    VectorMath::multiplyByScalar(realData(), 0.5, realData(), halfSize);
-    VectorMath::multiplyByScalar(imagData(), 0.5, imagData(), halfSize);
+    VectorMath::multiplyByScalar(realData().data(), 0.5, realData().data(), halfSize);
+    VectorMath::multiplyByScalar(imagData().data(), 0.5, imagData().data(), halfSize);
 }
 
 void FFTFrame::doInverseFFT(float* data)
@@ -148,16 +148,6 @@
 {
 }
 
-float* FFTFrame::realData() const
-{
-    return m_frame.realp;
-}
-    
-float* FFTFrame::imagData() const
-{
-    return m_frame.imagp;
-}
-
 } // namespace WebCore
 
 #endif // #if OS(DARWIN)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to