OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010, Google Inc. All rights reserved. | 2 * Copyright (C) 2010, Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 | 398 |
399 void AudioBufferSourceNode::clampGrainParameters(const AudioBuffer* buffer) | 399 void AudioBufferSourceNode::clampGrainParameters(const AudioBuffer* buffer) |
400 { | 400 { |
401 ASSERT(buffer); | 401 ASSERT(buffer); |
402 | 402 |
403 // We have a buffer so we can clip the offset and duration to lie within the
buffer. | 403 // We have a buffer so we can clip the offset and duration to lie within the
buffer. |
404 double bufferDuration = buffer->duration(); | 404 double bufferDuration = buffer->duration(); |
405 | 405 |
406 m_grainOffset = clampTo(m_grainOffset, 0.0, bufferDuration); | 406 m_grainOffset = clampTo(m_grainOffset, 0.0, bufferDuration); |
407 | 407 |
408 if (loop()) { | 408 // If the duration was not explicitly given, use the buffer duration to set
the grain |
| 409 // duration. Otherwise, we want to use the user-specified value, of course. |
| 410 if (!m_isDurationGiven) |
| 411 m_grainDuration = bufferDuration - m_grainOffset; |
| 412 |
| 413 if (m_isDurationGiven && loop()) { |
409 // We're looping a grain with a grain duration specified. Schedule the l
oop to stop after | 414 // We're looping a grain with a grain duration specified. Schedule the l
oop to stop after |
410 // grainDuration seconds after starting, possibly running the loop multi
ple times if | 415 // grainDuration seconds after starting, possibly running the loop multi
ple times if |
411 // grainDuration is larger than the buffer duration. The net effect is a
s if the user called | 416 // grainDuration is larger than the buffer duration. The net effect is a
s if the user called |
412 // stop(when + grainDuration). | 417 // stop(when + grainDuration). |
413 m_grainDuration = clampTo(m_grainDuration, 0.0, std::numeric_limits<doub
le>::infinity()); | 418 m_grainDuration = clampTo(m_grainDuration, 0.0, std::numeric_limits<doub
le>::infinity()); |
414 m_endTime = m_startTime + m_grainDuration; | 419 m_endTime = m_startTime + m_grainDuration; |
415 } else { | 420 } else { |
416 m_grainDuration = clampTo(m_grainDuration, 0.0, bufferDuration - m_grain
Offset); | 421 m_grainDuration = clampTo(m_grainDuration, 0.0, bufferDuration - m_grain
Offset); |
417 } | 422 } |
418 | 423 |
419 // We call timeToSampleFrame here since at playbackRate == 1 we don't want t
o go through | 424 // We call timeToSampleFrame here since at playbackRate == 1 we don't want t
o go through |
420 // linear interpolation at a sub-sample position since it will degrade the q
uality. When | 425 // linear interpolation at a sub-sample position since it will degrade the q
uality. When |
421 // aligned to the sample-frame the playback will be identical to the PCM dat
a stored in the | 426 // aligned to the sample-frame the playback will be identical to the PCM dat
a stored in the |
422 // buffer. Since playbackRate == 1 is very common, it's worth considering qu
ality. | 427 // buffer. Since playbackRate == 1 is very common, it's worth considering qu
ality. |
423 m_virtualReadIndex = AudioUtilities::timeToSampleFrame(m_grainOffset, buffer
->sampleRate()); | 428 m_virtualReadIndex = AudioUtilities::timeToSampleFrame(m_grainOffset, buffer
->sampleRate()); |
424 } | 429 } |
425 | 430 |
426 void AudioBufferSourceNode::start(double when, ExceptionState& exceptionState) | 431 void AudioBufferSourceNode::start(double when, ExceptionState& exceptionState) |
427 { | 432 { |
428 AudioScheduledSourceNode::start(when, exceptionState); | 433 AudioScheduledSourceNode::start(when, exceptionState); |
429 } | 434 } |
430 | 435 |
431 void AudioBufferSourceNode::start(double when, double grainOffset, ExceptionStat
e& exceptionState) | 436 void AudioBufferSourceNode::start(double when, double grainOffset, ExceptionStat
e& exceptionState) |
432 { | 437 { |
433 start(when, grainOffset, buffer() ? buffer()->duration() : 0, exceptionState
); | 438 startSource(when, grainOffset, buffer() ? buffer()->duration() : 0, false, e
xceptionState); |
434 } | 439 } |
435 | 440 |
436 void AudioBufferSourceNode::start(double when, double grainOffset, double grainD
uration, ExceptionState& exceptionState) | 441 void AudioBufferSourceNode::start(double when, double grainOffset, double grainD
uration, ExceptionState& exceptionState) |
437 { | 442 { |
| 443 startSource(when, grainOffset, grainDuration, true, exceptionState); |
| 444 } |
| 445 |
| 446 void AudioBufferSourceNode::startSource(double when, double grainOffset, double
grainDuration, bool isDurationGiven, ExceptionState& exceptionState) |
| 447 { |
438 ASSERT(isMainThread()); | 448 ASSERT(isMainThread()); |
439 | 449 |
440 if (m_playbackState != UNSCHEDULED_STATE) { | 450 if (m_playbackState != UNSCHEDULED_STATE) { |
441 exceptionState.throwDOMException( | 451 exceptionState.throwDOMException( |
442 InvalidStateError, | 452 InvalidStateError, |
443 "cannot call start more than once."); | 453 "cannot call start more than once."); |
444 return; | 454 return; |
445 } | 455 } |
446 | 456 |
447 if (when < 0) { | 457 if (when < 0) { |
(...skipping 10 matching lines...) Expand all Loading... |
458 return; | 468 return; |
459 } | 469 } |
460 | 470 |
461 if (grainDuration < 0) { | 471 if (grainDuration < 0) { |
462 exceptionState.throwDOMException( | 472 exceptionState.throwDOMException( |
463 InvalidStateError, | 473 InvalidStateError, |
464 "Duration must be a non-negative number: " + String::number(grainDur
ation)); | 474 "Duration must be a non-negative number: " + String::number(grainDur
ation)); |
465 return; | 475 return; |
466 } | 476 } |
467 | 477 |
| 478 m_isDurationGiven = isDurationGiven; |
468 m_isGrain = true; | 479 m_isGrain = true; |
469 m_grainOffset = grainOffset; | 480 m_grainOffset = grainOffset; |
470 m_grainDuration = grainDuration; | 481 m_grainDuration = grainDuration; |
471 | 482 |
472 m_startTime = when; | 483 m_startTime = when; |
473 | 484 |
474 if (buffer()) | 485 if (buffer()) |
475 clampGrainParameters(buffer()); | 486 clampGrainParameters(buffer()); |
476 | 487 |
477 m_playbackState = SCHEDULED_STATE; | 488 m_playbackState = SCHEDULED_STATE; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 { | 569 { |
559 visitor->trace(m_buffer); | 570 visitor->trace(m_buffer); |
560 visitor->trace(m_playbackRate); | 571 visitor->trace(m_playbackRate); |
561 visitor->trace(m_pannerNode); | 572 visitor->trace(m_pannerNode); |
562 AudioScheduledSourceNode::trace(visitor); | 573 AudioScheduledSourceNode::trace(visitor); |
563 } | 574 } |
564 | 575 |
565 } // namespace blink | 576 } // namespace blink |
566 | 577 |
567 #endif // ENABLE(WEB_AUDIO) | 578 #endif // ENABLE(WEB_AUDIO) |
OLD | NEW |