Skip to content

Commit 5bc062f

Browse files
committed
Audio buffer may contain more frames than decoded.
https://bugs.webkit.org/show_bug.cgi?id=228732 rdar://problem/81447014 Reviewed by Eric Carlson. Source/WebCore: It is necessary to call repeatedly ExtAudioFileRead until it explicitly indicates that it reached EOF. Test: webaudio/decode-audio-data-wav.html. * platform/audio/cocoa/AudioFileReaderCocoa.cpp: (WebCore::AudioFileReader::createBus): Ensure that all frames have been decoded and trim length to the actual number of frames returned. This was already done for the webm case. LayoutTests: * platform/mac/TestExpectations: * webaudio/decode-audio-data-wav-expected.txt: Added. * webaudio/decode-audio-data-wav.html: Added. * webaudio/pinknoise.wav: Added. Generated with command sox -b 16 -r 44100 -n pinknoise.wav synth 4 pinknoise Canonical link: https://commits.webkit.org/240456@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@280948 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent 20f60aa commit 5bc062f

7 files changed

Lines changed: 131 additions & 8 deletions

File tree

LayoutTests/ChangeLog

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
2021-08-11 Jean-Yves Avenard <jya@apple.com>
2+
3+
Audio buffer may contain more frames than decoded.
4+
https://bugs.webkit.org/show_bug.cgi?id=228732
5+
rdar://problem/81447014
6+
7+
Reviewed by Eric Carlson.
8+
9+
* platform/mac/TestExpectations:
10+
* webaudio/decode-audio-data-wav-expected.txt: Added.
11+
* webaudio/decode-audio-data-wav.html: Added.
12+
* webaudio/pinknoise.wav: Added. Generated with command
13+
sox -b 16 -r 44100 -n pinknoise.wav synth 4 pinknoise
14+
115
2021-08-11 Wenson Hsieh <wenson_hsieh@apple.com>
216

317
[ iOS ] fast/scrolling/ios/click-events-during-momentum-scroll-in-overflow-after-tap-on-body.html is a flaky timeout

LayoutTests/platform/mac/TestExpectations

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2266,8 +2266,9 @@ webkit.org/b/226299 [ BigSur ] http/tests/performance/performance-resource-timin
22662266
[ Monterey ] imported/w3c/web-platform-tests/html/canvas/element/imagebitmap/createImageBitmap-flipY.html [ Timeout ]
22672267
[ Monterey ] imported/w3c/web-platform-tests/html/canvas/element/imagebitmap/createImageBitmap-serializable.html [ Timeout ]
22682268

2269-
# rdar://80344665 ([ Monterey ] webaudio/codec-tests/mp3/128kbps-44khz.html is a constant audio failure)
2270-
[ Monterey ] webaudio/codec-tests/mp3/128kbps-44khz.html [ Failure ]
2269+
[ BigSur Monterey ] webaudio/codec-tests/mp3/128kbps-44khz.html [ Pass ]
2270+
[ BigSur Monterey ] webaudio/Panner/hrtf-database.html [ Pass ]
2271+
[ BigSur Monterey ] webaudio/codec-tests/aac/vbr-128kbps-44khz.html [ Pass ]
22712272

22722273
# rdar://80347712 ([ Monterey ] media/video-src-blob-replay.html is a flaky timeout)
22732274
[ Monterey ] media/video-src-blob-replay.html [ Timeout ]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
Test that decoding an WAV isn't incorrectly receiving silence at the end
2+
3+
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
4+
5+
6+
PASS Successfully decoded content
7+
PASS Decoding returned the right number of frames.
8+
PASS Decoding returned the right number of frames.
9+
PASS All frames got decoded with no silence.
10+
PASS successfullyParsed is true
11+
12+
TEST COMPLETE
13+
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<script src="../resources/js-test.js"></script>
5+
<script type="text/javascript" src="resources/audio-testing.js"></script>
6+
<script src="resources/audio-file-utils.js"></script>
7+
<body>
8+
<script>
9+
description("Test that decoding an WAV isn't incorrectly receiving silence at the end");
10+
11+
window.jsTestIsAsync = true;
12+
13+
var context = new window.AudioContext({ sampleRate: 44100 });
14+
var request = new XMLHttpRequest();
15+
request.open("GET", 'pinknoise.wav', true);
16+
request.responseType = "arraybuffer";
17+
18+
request.onload = function() {
19+
context.decodeAudioData(request.response, (buffer) => {
20+
testPassed("Successfully decoded content");
21+
// File is exactly 4s @ 44100Hz
22+
if (buffer.length === 176400)
23+
testPassed("Decoding returned the right number of frames.");
24+
else {
25+
testFailed("Decoding returned the wrong number of frames: " + buffer.length);
26+
finishJSTest();
27+
return;
28+
}
29+
// convert to 32 bits float WAV.
30+
const wavData = createAudioData(buffer, true /* asFloat */);
31+
context.decodeAudioData(wavData.buffer, (buffer) => {
32+
if (buffer.length === 176400)
33+
testPassed("Decoding returned the right number of frames.");
34+
else {
35+
testFailed("Decoding returned the wrong number of frames: " + buffer.length);
36+
finishJSTest();
37+
return;
38+
}
39+
const decodedData = buffer.getChannelData(0);
40+
let consecutiveSilent = 0
41+
for (const sample of decodedData) {
42+
if (sample == 0 && ++consecutiveSilent > 3) {
43+
testFailed("Found silence content.");
44+
break;
45+
} else if (sample)
46+
consecutiveSilent = 0
47+
}
48+
if (!consecutiveSilent)
49+
testPassed("All frames got decoded with no silence.");
50+
finishJSTest();
51+
}, () => {
52+
testFailed("Failed to decode intermediary file");
53+
finishJSTest();
54+
});
55+
}, () => {
56+
testFailed("Failed to decode file");
57+
finishJSTest();
58+
});
59+
}
60+
request.send();
61+
62+
</script>
63+
</body>
64+
</html>

LayoutTests/webaudio/pinknoise.wav

345 KB
Binary file not shown.

Source/WebCore/ChangeLog

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
2021-08-11 Jean-Yves Avenard <jya@apple.com>
2+
3+
Audio buffer may contain more frames than decoded.
4+
https://bugs.webkit.org/show_bug.cgi?id=228732
5+
rdar://problem/81447014
6+
7+
Reviewed by Eric Carlson.
8+
9+
It is necessary to call repeatedly ExtAudioFileRead until it explicitly indicates that
10+
it reached EOF.
11+
Test: webaudio/decode-audio-data-wav.html.
12+
13+
* platform/audio/cocoa/AudioFileReaderCocoa.cpp:
14+
(WebCore::AudioFileReader::createBus): Ensure that all frames have been decoded and
15+
trim length to the actual number of frames returned.
16+
This was already done for the webm case.
17+
118
2021-08-11 Chris Dumez <cdumez@apple.com>
219

320
<a rel="opener noopener" target="_blank"> should create a window without opener

Source/WebCore/platform/audio/cocoa/AudioFileReaderCocoa.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -576,21 +576,35 @@ RefPtr<AudioBus> AudioFileReader::createBus(float sampleRate, bool mixToMono)
576576
auto decodedFrames = decodeWebMData(*bufferList, numberOfFrames, *inFormat, outFormat);
577577
if (!decodedFrames)
578578
return nullptr;
579-
// The actual decoded number of frames may not match the number of frames calculated
580-
// while demuxing as frames can be trimmed. It will always be lower.
581-
audioBus->setLength(*decodedFrames);
582579
numberOfFrames = *decodedFrames;
583580
#endif
584581
} else {
585582
if (PAL::ExtAudioFileSetProperty(m_extAudioFileRef, kExtAudioFileProperty_ClientDataFormat, sizeof(AudioStreamBasicDescription), &outFormat) != noErr)
586583
return nullptr;
587584

588585
// Read from the file (or in-memory version)
589-
UInt32 framesToRead = numberOfFrames;
590-
if (PAL::ExtAudioFileRead(m_extAudioFileRef, &framesToRead, bufferList) != noErr)
591-
return nullptr;
586+
size_t framesLeftToRead = numberOfFrames;
587+
size_t framesRead = 0;
588+
UInt32 framesToRead;
589+
do {
590+
framesToRead = std::min<size_t>(std::numeric_limits<UInt32>::max(), framesLeftToRead);
591+
if (PAL::ExtAudioFileRead(m_extAudioFileRef, &framesToRead, bufferList) != noErr)
592+
return nullptr;
593+
framesRead += framesToRead;
594+
RELEASE_ASSERT(framesRead <= numberOfFrames, "We read more than what we have room for");
595+
framesLeftToRead -= framesToRead;
596+
for (size_t i = 0; i < numberOfChannels; ++i) {
597+
bufferList->mBuffers[i].mDataByteSize = (numberOfFrames - framesRead) * sizeof(float);
598+
bufferList->mBuffers[i].mData = static_cast<float*>(bufferList->mBuffers[i].mData) + framesToRead;
599+
}
600+
} while (framesToRead);
601+
numberOfFrames = framesRead;
592602
}
593603

604+
// The actual decoded number of frames may not match the number of frames calculated
605+
// while demuxing as frames can be trimmed. It will always be lower.
606+
audioBus->setLength(numberOfFrames);
607+
594608
if (mixToMono && numberOfChannels == 2) {
595609
// Mix stereo down to mono
596610
float* destL = audioBus->channel(0)->mutableData();

0 commit comments

Comments
 (0)