Changeset 267386 in webkit
- Timestamp:
- Sep 21, 2020, 5:17:33 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/webaudio/AudioBufferSource/audiobuffersource-loop-grain-no-duration-expected.txt (modified) (1 diff)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp (modified) (3 diffs)
-
Source/WebCore/Modules/webaudio/AudioBufferSourceNode.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r267384 r267386 1 2020-09-21 Chris Dumez <cdumez@apple.com> 2 3 AudioBufferSourceNode should update grain parameters when buffer is set after rendering has started 4 https://bugs.webkit.org/show_bug.cgi?id=216808 5 6 Reviewed by Eric Carlson. 7 8 Rebaseline test that is now passing. 9 10 * webaudio/AudioBufferSource/audiobuffersource-loop-grain-no-duration-expected.txt: 11 1 12 2020-09-21 Chris Dumez <cdumez@apple.com> 2 13 -
trunk/LayoutTests/webaudio/AudioBufferSource/audiobuffersource-loop-grain-no-duration-expected.txt
r267245 r267386 8 8 PASS < [loop-count] All assertions passed. (total 1 assertions) 9 9 PASS > [delayed-start] 10 FAIL X The content of the left and right channel expected to be equal to the array [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0...] but differs in 8128 places: 11 Index Actual Expected 12 [8193] 7.8125000000000000e-3 0.0000000000000000e+0 13 [8194] 1.5625000000000000e-2 0.0000000000000000e+0 14 [8195] 2.3437500000000000e-2 0.0000000000000000e+0 15 [8196] 3.1250000000000000e-2 0.0000000000000000e+0 16 ...and 8124 more errors. assert_true: expected true got false 17 FAIL < [delayed-start] 1 out of 1 assertions were failed. assert_true: expected true got false 18 FAIL # AUDIT TASK RUNNER FINISHED: 1 out of 2 tasks were failed. assert_true: expected true got false 10 PASS The content of the left and right channel is identical to the array [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0...]. 11 PASS < [delayed-start] All assertions passed. (total 1 assertions) 12 PASS # AUDIT TASK RUNNER FINISHED: 2 tasks ran successfully. 19 13 -
trunk/Source/WebCore/ChangeLog
r267383 r267386 1 2020-09-21 Chris Dumez <cdumez@apple.com> 2 3 AudioBufferSourceNode should update grain parameters when buffer is set after rendering has started 4 https://bugs.webkit.org/show_bug.cgi?id=216808 5 6 Reviewed by Eric Carlson. 7 8 AudioBufferSourceNode should update grain parameters when buffer is set after rendering has 9 started. The grain parameters need to be adjusted so that they make sense given the buffer 10 length. Previously, we would only update grain parameters in AudioBufferSourceNode::startPlaying(), 11 when a buffer is set. We would fail to update those grain parameters when the buffer is set, 12 in setBuffer(), if startPlaying() has already been called. 13 14 No new tests, rebaselined existing test. 15 16 * Modules/webaudio/AudioBufferSourceNode.cpp: 17 (WebCore::AudioBufferSourceNode::setBuffer): 18 (WebCore::AudioBufferSourceNode::startLater): 19 (WebCore::AudioBufferSourceNode::startPlaying): 20 (WebCore::AudioBufferSourceNode::updateGrainParameters): 21 * Modules/webaudio/AudioBufferSourceNode.h: 22 1 23 2020-09-21 Chris Dumez <cdumez@apple.com> 2 24 -
trunk/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp
r267170 r267386 451 451 m_virtualReadIndex = 0; 452 452 m_buffer = WTFMove(buffer); 453 454 // In case the buffer gets set after playback has started, we need to clamp the grain parameters now. 455 if (m_isGrain) 456 adjustGrainParameters(); 457 453 458 return { }; 454 459 } … … 459 464 } 460 465 461 ExceptionOr<void> AudioBufferSourceNode::startLater(double when, double grainOffset, Optional<double> optionalGrainDuration) 462 { 463 double grainDuration = 0; 464 if (optionalGrainDuration) 465 grainDuration = optionalGrainDuration.value(); 466 else if (buffer()) 467 grainDuration = buffer()->duration() - grainOffset; 468 466 ExceptionOr<void> AudioBufferSourceNode::startLater(double when, double grainOffset, Optional<double> grainDuration) 467 { 469 468 return startPlaying(when, grainOffset, grainDuration); 470 469 } 471 470 472 ExceptionOr<void> AudioBufferSourceNode::startPlaying(double when, double grainOffset, doublegrainDuration)471 ExceptionOr<void> AudioBufferSourceNode::startPlaying(double when, double grainOffset, Optional<double> grainDuration) 473 472 { 474 473 ASSERT(isMainThread()); 475 ALWAYS_LOG(LOGIDENTIFIER, "when = ", when, ", offset = ", grainOffset, ", duration = ", grainDuration );474 ALWAYS_LOG(LOGIDENTIFIER, "when = ", when, ", offset = ", grainOffset, ", duration = ", grainDuration.valueOr(0)); 476 475 477 476 context().nodeWillBeginPlayback(); … … 486 485 return Exception { RangeError, "offset value should be positive"_s }; 487 486 488 if ( !std::isfinite(grainDuration) || (grainDuration < 0))487 if (grainDuration && (!std::isfinite(*grainDuration) || (*grainDuration < 0))) 489 488 return Exception { RangeError, "duration value should be positive"_s }; 489 490 // This synchronizes with process(). 491 auto locker = holdLock(m_processMutex); 490 492 491 493 m_isGrain = true; 492 494 m_grainOffset = grainOffset; 493 m_grainDuration = grainDuration; 495 m_grainDuration = grainDuration.valueOr(0); 496 m_wasGrainDurationGiven = !!grainDuration; 494 497 m_startTime = when; 495 498 496 if (buffer()) { 497 // Do sanity checking of grain parameters versus buffer size. 498 double bufferDuration = buffer()->duration(); 499 500 m_grainOffset = std::min(bufferDuration, grainOffset); 501 502 double maxDuration = bufferDuration - m_grainOffset; 503 m_grainDuration = std::min(maxDuration, grainDuration); 504 505 // We call timeToSampleFrame here since at playbackRate == 1 we don't want to go through linear interpolation 506 // at a sub-sample position since it will degrade the quality. 507 // When aligned to the sample-frame the playback will be identical to the PCM data stored in the buffer. 508 // Since playbackRate == 1 is very common, it's worth considering quality. 509 if (playbackRate().value() < 0) 510 m_virtualReadIndex = AudioUtilities::timeToSampleFrame(m_grainOffset + m_grainDuration, buffer()->sampleRate()) - 1; 511 else 512 m_virtualReadIndex = AudioUtilities::timeToSampleFrame(m_grainOffset, buffer()->sampleRate()); 513 } 499 adjustGrainParameters(); 500 514 501 m_playbackState = SCHEDULED_STATE; 515 502 516 503 return { }; 504 } 505 506 void AudioBufferSourceNode::adjustGrainParameters() 507 { 508 ASSERT(m_processMutex.isHeld()); 509 510 auto buffer = this->buffer(); 511 if (!buffer) 512 return; 513 514 // Do sanity checking of grain parameters versus buffer size. 515 double bufferDuration = buffer->duration(); 516 517 m_grainOffset = std::min(bufferDuration, m_grainOffset); 518 519 double maxDuration = bufferDuration - m_grainOffset; 520 521 if (m_wasGrainDurationGiven) 522 m_grainDuration = std::min(m_grainDuration, maxDuration); 523 else 524 m_grainDuration = maxDuration; 525 526 // We call timeToSampleFrame here since at playbackRate == 1 we don't want to go through linear interpolation 527 // at a sub-sample position since it will degrade the quality. 528 // When aligned to the sample-frame the playback will be identical to the PCM data stored in the buffer. 529 // Since playbackRate == 1 is very common, it's worth considering quality. 530 if (playbackRate().value() < 0) 531 m_virtualReadIndex = AudioUtilities::timeToSampleFrame(m_grainOffset + m_grainDuration, buffer->sampleRate()) - 1; 532 else 533 m_virtualReadIndex = AudioUtilities::timeToSampleFrame(m_grainOffset, buffer->sampleRate()); 517 534 } 518 535 -
trunk/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.h
r266794 r267386 100 100 virtual bool shouldThrowOnAttemptToOverwriteBuffer() const { return true; } 101 101 102 ExceptionOr<void> startPlaying(double when, double grainOffset, double grainDuration); 102 ExceptionOr<void> startPlaying(double when, double grainOffset, Optional<double> grainDuration); 103 void adjustGrainParameters(); 103 104 104 105 // Returns true on success. … … 135 136 double m_grainOffset { 0 }; // in seconds 136 137 double m_grainDuration; // in seconds 138 double m_wasGrainDurationGiven { false }; 137 139 138 140 // totalPitchRate() returns the instantaneous pitch rate (non-time preserving).
Note:
See TracChangeset
for help on using the changeset viewer.