⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 199066 in webkit


Ignore:
Timestamp:
Apr 5, 2016, 12:38:45 PM (11 years ago)
Author:
matthew_hanson@apple.com
Message:

Merge r198035. rdar://problem/25467558

Location:
branches/safari-601.1.46-branch/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • branches/safari-601.1.46-branch/Source/WebCore/ChangeLog

    r198957 r199066  
     12016-04-05  Matthew Hanson  <matthew_hanson@apple.com>
     2
     3        Merge r198035. rdar://problem/25467558
     4
     5    2016-03-10  Jer Noble  <jer.noble@apple.com>
     6
     7            Web Audio becomes distorted after sample rate changes
     8            https://bugs.webkit.org/show_bug.cgi?id=154538
     9            <rdar://problem/24771292>
     10
     11            Reviewed by Darin Adler.
     12
     13            When the underlying audio hardware sample rate changes, the AudioUnit render callback will begin asking
     14            for fewer or more frames. For example, when the sample rate goes from 44.1kHz to 48kHz, it will ask for
     15            118 samples instead of 128. (And vice-versa, 140 samples instead of 128.) But the Web Audio engine can only
     16            really handle requests in multiples of 128 samples. In the case where there are requests for < 128 samples,
     17            actually render 128, but save off the unrequested samples in a separate bus. Then fill that bus during the
     18            next request.
     19
     20            * platform/audio/AudioBus.cpp:
     21            (WebCore::AudioBus::copyFromRange): Added utility method.
     22            * platform/audio/AudioBus.h:
     23            * platform/audio/ios/AudioDestinationIOS.cpp:
     24            (WebCore::AudioDestinationIOS::AudioDestinationIOS): Create a "spare" bus.
     25            (WebCore::assignAudioBuffersToBus): Moved from inside render.
     26            (WebCore::AudioDestinationIOS::render): Save off extra samples to the "spare" bus.
     27            * platform/audio/ios/AudioDestinationIOS.h:
     28
    1292016-04-01  Matthew Hanson  <matthew_hanson@apple.com>
    230
  • branches/safari-601.1.46-branch/Source/WebCore/platform/audio/AudioBus.cpp

    r198957 r199066  
    214214}
    215215
     216void AudioBus::copyFromRange(const AudioBus& sourceBus, unsigned startFrame, unsigned endFrame)
     217{
     218    if (!topologyMatches(sourceBus)) {
     219        ASSERT_NOT_REACHED();
     220        zero();
     221        return;
     222    }
     223
     224    size_t numberOfSourceFrames = sourceBus.length();
     225    bool isRangeSafe = startFrame < endFrame && endFrame <= numberOfSourceFrames;
     226    ASSERT(isRangeSafe);
     227    if (!isRangeSafe) {
     228        zero();
     229        return;
     230    }
     231
     232    unsigned numberOfChannels = this->numberOfChannels();
     233    ASSERT(numberOfChannels <= MaxBusChannels);
     234    if (numberOfChannels > MaxBusChannels) {
     235        zero();
     236        return;
     237    }
     238
     239    for (unsigned i = 0; i < numberOfChannels; ++i)
     240        channel(i)->copyFromRange(sourceBus.channel(i), startFrame, endFrame);
     241}
     242
    216243void AudioBus::copyFrom(const AudioBus& sourceBus, ChannelInterpretation channelInterpretation)
    217244{
  • branches/safari-601.1.46-branch/Source/WebCore/platform/audio/AudioBus.h

    r198957 r199066  
    123123
    124124    // Copies the samples from the source bus to this one.
     125    void copyFromRange(const AudioBus& sourceBus, unsigned startFrame, unsigned endFrame);
     126
     127    // Copies the samples from the source bus to this one.
    125128    // This is just a simple per-channel copy if the number of channels match, otherwise an up-mix or down-mix is done.
    126129    void copyFrom(const AudioBus& sourceBus, ChannelInterpretation = Speakers);
  • branches/safari-601.1.46-branch/Source/WebCore/platform/audio/ios/AudioDestinationIOS.cpp

    r198957 r199066  
    101101    , m_callback(callback)
    102102    , m_renderBus(AudioBus::create(2, kRenderBufferSize, false))
     103    , m_spareBus(AudioBus::create(2, kRenderBufferSize, true))
    103104    , m_sampleRate(sampleRate)
    104105    , m_isPlaying(false)
    … …  
    199200}
    200201
     202static void assignAudioBuffersToBus(AudioBuffer* buffers, AudioBus& bus, UInt32 numberOfBuffers, UInt32 numberOfFrames, UInt32 frameOffset, UInt32 framesThisTime)
     203{
     204    for (UInt32 i = 0; i < numberOfBuffers; ++i) {
     205        UInt32 bytesPerFrame = buffers[i].mDataByteSize / numberOfFrames;
     206        UInt32 byteOffset = frameOffset * bytesPerFrame;
     207        float* memory = reinterpret_cast<float*>(reinterpret_cast<char*>(buffers[i].mData) + byteOffset);
     208        bus.setChannelMemory(i, memory, framesThisTime);
     209    }
     210}
     211
    201212// Pulls on our provider to get rendered audio stream.
    202213OSStatus AudioDestinationIOS::render(UInt32 numberOfFrames, AudioBufferList* ioData)
    203214{
    204215    AudioBuffer* buffers = ioData->mBuffers;
    205     for (UInt32 frameOffset = 0; frameOffset + kRenderBufferSize <= numberOfFrames; frameOffset += kRenderBufferSize) {
    206         UInt32 remainingFrames = std::min<UInt32>(kRenderBufferSize, numberOfFrames - frameOffset);
    207         for (UInt32 i = 0; i < ioData->mNumberBuffers; ++i) {
    208             UInt32 bytesPerFrame = buffers[i].mDataByteSize / numberOfFrames;
    209             UInt32 byteOffset = frameOffset * bytesPerFrame;
    210             float* memory = (float*)((char*)buffers[i].mData + byteOffset);
    211             m_renderBus->setChannelMemory(i, memory, remainingFrames);
     216    UInt32 numberOfBuffers = ioData->mNumberBuffers;
     217    UInt32 framesRemaining = numberOfFrames;
     218    UInt32 frameOffset = 0;
     219    while (framesRemaining > 0) {
     220        if (m_firstSpareFrame && m_lastSpareFrame) {
     221            ASSERT(m_firstSpareFrame < m_lastSpareFrame);
     222            UInt32 framesThisTime = m_lastSpareFrame - m_firstSpareFrame;
     223            assignAudioBuffersToBus(buffers, *m_renderBus, numberOfBuffers, numberOfFrames, frameOffset, framesThisTime);
     224            m_renderBus->copyFromRange(*m_spareBus, m_firstSpareFrame, m_lastSpareFrame);
     225            frameOffset += framesThisTime;
     226            framesRemaining -= framesThisTime;
     227            m_firstSpareFrame = 0;
     228            m_lastSpareFrame = 0;
    212229        }
    213         m_callback.render(0, m_renderBus.get(), remainingFrames);
     230
     231        UInt32 framesThisTime = std::min<UInt32>(kRenderBufferSize, framesRemaining);
     232        assignAudioBuffersToBus(buffers, *m_renderBus, numberOfBuffers, numberOfFrames, frameOffset, framesThisTime);
     233
     234        if (framesThisTime < kRenderBufferSize) {
     235            m_callback.render(0, m_spareBus.get(), kRenderBufferSize);
     236            m_renderBus->copyFromRange(*m_spareBus, 0, framesThisTime);
     237            m_firstSpareFrame = framesThisTime;
     238            m_lastSpareFrame = kRenderBufferSize - 1;
     239        } else
     240            m_callback.render(0, m_renderBus.get(), framesThisTime);
     241        frameOffset += framesThisTime;
     242        framesRemaining -= framesThisTime;
    214243    }
    215244
  • branches/safari-601.1.46-branch/Source/WebCore/platform/audio/ios/AudioDestinationIOS.h

    r198957 r199066  
    6666    AudioIOCallback& m_callback;
    6767    RefPtr<AudioBus> m_renderBus;
     68    RefPtr<AudioBus> m_spareBus;
     69    unsigned m_firstSpareFrame { 0 };
     70    unsigned m_lastSpareFrame { 0 };
    6871
    6972    double m_sampleRate;
Note: See TracChangeset for help on using the changeset viewer.