| 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 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 | 244 |
| 245 // We've resolved the promise. Remove it now. | 245 // We've resolved the promise. Remove it now. |
| 246 ASSERT(m_decodeAudioResolvers.contains(resolver)); | 246 ASSERT(m_decodeAudioResolvers.contains(resolver)); |
| 247 m_decodeAudioResolvers.remove(resolver); | 247 m_decodeAudioResolvers.remove(resolver); |
| 248 } | 248 } |
| 249 | 249 |
| 250 AudioBufferSourceNode* AbstractAudioContext::createBufferSource(ExceptionState&
exceptionState) | 250 AudioBufferSourceNode* AbstractAudioContext::createBufferSource(ExceptionState&
exceptionState) |
| 251 { | 251 { |
| 252 ASSERT(isMainThread()); | 252 ASSERT(isMainThread()); |
| 253 | 253 |
| 254 if (isContextClosed()) { | 254 AudioBufferSourceNode* node = AudioBufferSourceNode::create(*this, exception
State); |
| 255 throwExceptionForClosedState(exceptionState); | |
| 256 return nullptr; | |
| 257 } | |
| 258 | |
| 259 AudioBufferSourceNode* node = AudioBufferSourceNode::create(*this, sampleRat
e()); | |
| 260 | 255 |
| 261 // Do not add a reference to this source node now. The reference will be add
ed when start() is | 256 // Do not add a reference to this source node now. The reference will be add
ed when start() is |
| 262 // called. | 257 // called. |
| 263 | 258 |
| 264 return node; | 259 return node; |
| 265 } | 260 } |
| 266 | 261 |
| 267 MediaElementAudioSourceNode* AbstractAudioContext::createMediaElementSource(HTML
MediaElement* mediaElement, ExceptionState& exceptionState) | 262 MediaElementAudioSourceNode* AbstractAudioContext::createMediaElementSource(HTML
MediaElement* mediaElement, ExceptionState& exceptionState) |
| 268 { | 263 { |
| 269 ASSERT(isMainThread()); | 264 ASSERT(isMainThread()); |
| 270 | 265 |
| 271 if (isContextClosed()) { | 266 return MediaElementAudioSourceNode::create(*this, *mediaElement, exceptionSt
ate); |
| 272 throwExceptionForClosedState(exceptionState); | |
| 273 return nullptr; | |
| 274 } | |
| 275 | |
| 276 // First check if this media element already has a source node. | |
| 277 if (mediaElement->audioSourceNode()) { | |
| 278 exceptionState.throwDOMException( | |
| 279 InvalidStateError, | |
| 280 "HTMLMediaElement already connected previously to a different MediaE
lementSourceNode."); | |
| 281 return nullptr; | |
| 282 } | |
| 283 | |
| 284 MediaElementAudioSourceNode* node = MediaElementAudioSourceNode::create(*thi
s, *mediaElement); | |
| 285 | |
| 286 mediaElement->setAudioSourceNode(node); | |
| 287 | |
| 288 notifySourceNodeStartedProcessing(node); // context keeps reference until no
de is disconnected | |
| 289 return node; | |
| 290 } | 267 } |
| 291 | 268 |
| 292 MediaStreamAudioSourceNode* AbstractAudioContext::createMediaStreamSource(MediaS
tream* mediaStream, ExceptionState& exceptionState) | 269 MediaStreamAudioSourceNode* AbstractAudioContext::createMediaStreamSource(MediaS
tream* mediaStream, ExceptionState& exceptionState) |
| 293 { | 270 { |
| 294 ASSERT(isMainThread()); | 271 ASSERT(isMainThread()); |
| 295 | 272 |
| 296 if (isContextClosed()) { | 273 return MediaStreamAudioSourceNode::create(*this, *mediaStream, exceptionStat
e); |
| 297 throwExceptionForClosedState(exceptionState); | |
| 298 return nullptr; | |
| 299 } | |
| 300 | |
| 301 MediaStreamTrackVector audioTracks = mediaStream->getAudioTracks(); | |
| 302 if (audioTracks.isEmpty()) { | |
| 303 exceptionState.throwDOMException( | |
| 304 InvalidStateError, | |
| 305 "MediaStream has no audio track"); | |
| 306 return nullptr; | |
| 307 } | |
| 308 | |
| 309 // Use the first audio track in the media stream. | |
| 310 MediaStreamTrack* audioTrack = audioTracks[0]; | |
| 311 OwnPtr<AudioSourceProvider> provider = audioTrack->createWebAudioSource(); | |
| 312 MediaStreamAudioSourceNode* node = MediaStreamAudioSourceNode::create(*this,
*mediaStream, audioTrack, provider.release()); | |
| 313 | |
| 314 // FIXME: Only stereo streams are supported right now. We should be able to
accept multi-channel streams. | |
| 315 node->setFormat(2, sampleRate()); | |
| 316 | |
| 317 notifySourceNodeStartedProcessing(node); // context keeps reference until no
de is disconnected | |
| 318 return node; | |
| 319 } | 274 } |
| 320 | 275 |
| 321 MediaStreamAudioDestinationNode* AbstractAudioContext::createMediaStreamDestinat
ion(ExceptionState& exceptionState) | 276 MediaStreamAudioDestinationNode* AbstractAudioContext::createMediaStreamDestinat
ion(ExceptionState& exceptionState) |
| 322 { | 277 { |
| 323 if (isContextClosed()) { | 278 ASSERT(isMainThread()); |
| 324 throwExceptionForClosedState(exceptionState); | |
| 325 return nullptr; | |
| 326 } | |
| 327 | 279 |
| 328 // Set number of output channels to stereo by default. | 280 // Set number of output channels to stereo by default. |
| 329 return MediaStreamAudioDestinationNode::create(*this, 2); | 281 return MediaStreamAudioDestinationNode::create(*this, 2, exceptionState); |
| 330 } | 282 } |
| 331 | 283 |
| 332 ScriptProcessorNode* AbstractAudioContext::createScriptProcessor(ExceptionState&
exceptionState) | 284 ScriptProcessorNode* AbstractAudioContext::createScriptProcessor(ExceptionState&
exceptionState) |
| 333 { | 285 { |
| 334 // Set number of input/output channels to stereo by default. | 286 ASSERT(isMainThread()); |
| 335 return createScriptProcessor(0, 2, 2, exceptionState); | 287 |
| 288 return ScriptProcessorNode::create(*this, exceptionState); |
| 336 } | 289 } |
| 337 | 290 |
| 338 ScriptProcessorNode* AbstractAudioContext::createScriptProcessor(size_t bufferSi
ze, ExceptionState& exceptionState) | 291 ScriptProcessorNode* AbstractAudioContext::createScriptProcessor(size_t bufferSi
ze, ExceptionState& exceptionState) |
| 339 { | 292 { |
| 340 // Set number of input/output channels to stereo by default. | 293 ASSERT(isMainThread()); |
| 341 return createScriptProcessor(bufferSize, 2, 2, exceptionState); | 294 |
| 295 return ScriptProcessorNode::create(*this, bufferSize, exceptionState); |
| 342 } | 296 } |
| 343 | 297 |
| 344 ScriptProcessorNode* AbstractAudioContext::createScriptProcessor(size_t bufferSi
ze, size_t numberOfInputChannels, ExceptionState& exceptionState) | 298 ScriptProcessorNode* AbstractAudioContext::createScriptProcessor(size_t bufferSi
ze, size_t numberOfInputChannels, ExceptionState& exceptionState) |
| 345 { | 299 { |
| 346 // Set number of output channels to stereo by default. | 300 ASSERT(isMainThread()); |
| 347 return createScriptProcessor(bufferSize, numberOfInputChannels, 2, exception
State); | 301 |
| 302 return ScriptProcessorNode::create(*this, bufferSize, numberOfInputChannels,
exceptionState); |
| 348 } | 303 } |
| 349 | 304 |
| 350 ScriptProcessorNode* AbstractAudioContext::createScriptProcessor(size_t bufferSi
ze, size_t numberOfInputChannels, size_t numberOfOutputChannels, ExceptionState&
exceptionState) | 305 ScriptProcessorNode* AbstractAudioContext::createScriptProcessor(size_t bufferSi
ze, size_t numberOfInputChannels, size_t numberOfOutputChannels, ExceptionState&
exceptionState) |
| 351 { | 306 { |
| 352 ASSERT(isMainThread()); | 307 ASSERT(isMainThread()); |
| 353 | 308 |
| 354 if (isContextClosed()) { | 309 return ScriptProcessorNode::create( |
| 355 throwExceptionForClosedState(exceptionState); | 310 *this, |
| 356 return nullptr; | 311 bufferSize, |
| 357 } | 312 numberOfInputChannels, |
| 358 | 313 numberOfOutputChannels, |
| 359 ScriptProcessorNode* node = ScriptProcessorNode::create(*this, sampleRate(),
bufferSize, numberOfInputChannels, numberOfOutputChannels); | 314 exceptionState); |
| 360 | |
| 361 if (!node) { | |
| 362 if (!numberOfInputChannels && !numberOfOutputChannels) { | |
| 363 exceptionState.throwDOMException( | |
| 364 IndexSizeError, | |
| 365 "number of input channels and output channels cannot both be zer
o."); | |
| 366 } else if (numberOfInputChannels > AbstractAudioContext::maxNumberOfChan
nels()) { | |
| 367 exceptionState.throwDOMException( | |
| 368 IndexSizeError, | |
| 369 "number of input channels (" + String::number(numberOfInputChann
els) | |
| 370 + ") exceeds maximum (" | |
| 371 + String::number(AbstractAudioContext::maxNumberOfChannels()) +
")."); | |
| 372 } else if (numberOfOutputChannels > AbstractAudioContext::maxNumberOfCha
nnels()) { | |
| 373 exceptionState.throwDOMException( | |
| 374 IndexSizeError, | |
| 375 "number of output channels (" + String::number(numberOfInputChan
nels) | |
| 376 + ") exceeds maximum (" | |
| 377 + String::number(AbstractAudioContext::maxNumberOfChannels()) +
")."); | |
| 378 } else { | |
| 379 exceptionState.throwDOMException( | |
| 380 IndexSizeError, | |
| 381 "buffer size (" + String::number(bufferSize) | |
| 382 + ") must be a power of two between 256 and 16384."); | |
| 383 } | |
| 384 return nullptr; | |
| 385 } | |
| 386 | |
| 387 notifySourceNodeStartedProcessing(node); // context keeps reference until we
stop making javascript rendering callbacks | |
| 388 return node; | |
| 389 } | 315 } |
| 390 | 316 |
| 391 StereoPannerNode* AbstractAudioContext::createStereoPanner(ExceptionState& excep
tionState) | 317 StereoPannerNode* AbstractAudioContext::createStereoPanner(ExceptionState& excep
tionState) |
| 392 { | 318 { |
| 393 ASSERT(isMainThread()); | 319 ASSERT(isMainThread()); |
| 394 if (isContextClosed()) { | |
| 395 throwExceptionForClosedState(exceptionState); | |
| 396 return nullptr; | |
| 397 } | |
| 398 | 320 |
| 399 return StereoPannerNode::create(*this, sampleRate()); | 321 return StereoPannerNode::create(*this, exceptionState); |
| 400 } | 322 } |
| 401 | 323 |
| 402 BiquadFilterNode* AbstractAudioContext::createBiquadFilter(ExceptionState& excep
tionState) | 324 BiquadFilterNode* AbstractAudioContext::createBiquadFilter(ExceptionState& excep
tionState) |
| 403 { | 325 { |
| 404 ASSERT(isMainThread()); | 326 ASSERT(isMainThread()); |
| 405 if (isContextClosed()) { | |
| 406 throwExceptionForClosedState(exceptionState); | |
| 407 return nullptr; | |
| 408 } | |
| 409 | 327 |
| 410 return BiquadFilterNode::create(*this, sampleRate()); | 328 return BiquadFilterNode::create(*this, exceptionState); |
| 411 } | 329 } |
| 412 | 330 |
| 413 WaveShaperNode* AbstractAudioContext::createWaveShaper(ExceptionState& exception
State) | 331 WaveShaperNode* AbstractAudioContext::createWaveShaper(ExceptionState& exception
State) |
| 414 { | 332 { |
| 415 ASSERT(isMainThread()); | 333 ASSERT(isMainThread()); |
| 416 if (isContextClosed()) { | |
| 417 throwExceptionForClosedState(exceptionState); | |
| 418 return nullptr; | |
| 419 } | |
| 420 | 334 |
| 421 return WaveShaperNode::create(*this); | 335 return WaveShaperNode::create(*this, exceptionState); |
| 422 } | 336 } |
| 423 | 337 |
| 424 PannerNode* AbstractAudioContext::createPanner(ExceptionState& exceptionState) | 338 PannerNode* AbstractAudioContext::createPanner(ExceptionState& exceptionState) |
| 425 { | 339 { |
| 426 ASSERT(isMainThread()); | 340 ASSERT(isMainThread()); |
| 427 if (isContextClosed()) { | |
| 428 throwExceptionForClosedState(exceptionState); | |
| 429 return nullptr; | |
| 430 } | |
| 431 | 341 |
| 432 return PannerNode::create(*this, sampleRate()); | 342 return PannerNode::create(*this, exceptionState); |
| 433 } | 343 } |
| 434 | 344 |
| 435 ConvolverNode* AbstractAudioContext::createConvolver(ExceptionState& exceptionSt
ate) | 345 ConvolverNode* AbstractAudioContext::createConvolver(ExceptionState& exceptionSt
ate) |
| 436 { | 346 { |
| 437 ASSERT(isMainThread()); | 347 ASSERT(isMainThread()); |
| 438 if (isContextClosed()) { | |
| 439 throwExceptionForClosedState(exceptionState); | |
| 440 return nullptr; | |
| 441 } | |
| 442 | 348 |
| 443 return ConvolverNode::create(*this, sampleRate()); | 349 return ConvolverNode::create(*this, exceptionState); |
| 444 } | 350 } |
| 445 | 351 |
| 446 DynamicsCompressorNode* AbstractAudioContext::createDynamicsCompressor(Exception
State& exceptionState) | 352 DynamicsCompressorNode* AbstractAudioContext::createDynamicsCompressor(Exception
State& exceptionState) |
| 447 { | 353 { |
| 448 ASSERT(isMainThread()); | 354 ASSERT(isMainThread()); |
| 449 if (isContextClosed()) { | |
| 450 throwExceptionForClosedState(exceptionState); | |
| 451 return nullptr; | |
| 452 } | |
| 453 | 355 |
| 454 return DynamicsCompressorNode::create(*this, sampleRate()); | 356 return DynamicsCompressorNode::create(*this, exceptionState); |
| 455 } | 357 } |
| 456 | 358 |
| 457 AnalyserNode* AbstractAudioContext::createAnalyser(ExceptionState& exceptionStat
e) | 359 AnalyserNode* AbstractAudioContext::createAnalyser(ExceptionState& exceptionStat
e) |
| 458 { | 360 { |
| 459 ASSERT(isMainThread()); | 361 ASSERT(isMainThread()); |
| 460 if (isContextClosed()) { | |
| 461 throwExceptionForClosedState(exceptionState); | |
| 462 return nullptr; | |
| 463 } | |
| 464 | 362 |
| 465 return AnalyserNode::create(*this, sampleRate()); | 363 return AnalyserNode::create(*this, exceptionState); |
| 466 } | 364 } |
| 467 | 365 |
| 468 GainNode* AbstractAudioContext::createGain(ExceptionState& exceptionState) | 366 GainNode* AbstractAudioContext::createGain(ExceptionState& exceptionState) |
| 469 { | 367 { |
| 470 ASSERT(isMainThread()); | 368 ASSERT(isMainThread()); |
| 471 if (isContextClosed()) { | |
| 472 throwExceptionForClosedState(exceptionState); | |
| 473 return nullptr; | |
| 474 } | |
| 475 | 369 |
| 476 return GainNode::create(*this, sampleRate()); | 370 return GainNode::create(*this, exceptionState); |
| 477 } | 371 } |
| 478 | 372 |
| 479 DelayNode* AbstractAudioContext::createDelay(ExceptionState& exceptionState) | 373 DelayNode* AbstractAudioContext::createDelay(ExceptionState& exceptionState) |
| 480 { | 374 { |
| 481 const double defaultMaxDelayTime = 1; | 375 ASSERT(isMainThread()); |
| 482 return createDelay(defaultMaxDelayTime, exceptionState); | 376 |
| 377 return DelayNode::create(*this, exceptionState); |
| 483 } | 378 } |
| 484 | 379 |
| 485 DelayNode* AbstractAudioContext::createDelay(double maxDelayTime, ExceptionState
& exceptionState) | 380 DelayNode* AbstractAudioContext::createDelay(double maxDelayTime, ExceptionState
& exceptionState) |
| 486 { | 381 { |
| 487 ASSERT(isMainThread()); | 382 ASSERT(isMainThread()); |
| 488 if (isContextClosed()) { | |
| 489 throwExceptionForClosedState(exceptionState); | |
| 490 return nullptr; | |
| 491 } | |
| 492 | 383 |
| 493 return DelayNode::create(*this, sampleRate(), maxDelayTime, exceptionState); | 384 return DelayNode::create(*this, maxDelayTime, exceptionState); |
| 494 } | 385 } |
| 495 | 386 |
| 496 ChannelSplitterNode* AbstractAudioContext::createChannelSplitter(ExceptionState&
exceptionState) | 387 ChannelSplitterNode* AbstractAudioContext::createChannelSplitter(ExceptionState&
exceptionState) |
| 497 { | 388 { |
| 498 const unsigned ChannelSplitterDefaultNumberOfOutputs = 6; | 389 ASSERT(isMainThread()); |
| 499 return createChannelSplitter(ChannelSplitterDefaultNumberOfOutputs, exceptio
nState); | 390 |
| 391 return ChannelSplitterNode::create(*this, exceptionState); |
| 500 } | 392 } |
| 501 | 393 |
| 502 ChannelSplitterNode* AbstractAudioContext::createChannelSplitter(size_t numberOf
Outputs, ExceptionState& exceptionState) | 394 ChannelSplitterNode* AbstractAudioContext::createChannelSplitter(size_t numberOf
Outputs, ExceptionState& exceptionState) |
| 503 { | 395 { |
| 504 ASSERT(isMainThread()); | 396 ASSERT(isMainThread()); |
| 505 | 397 |
| 506 if (isContextClosed()) { | 398 return ChannelSplitterNode::create(*this, numberOfOutputs, exceptionState); |
| 507 throwExceptionForClosedState(exceptionState); | |
| 508 return nullptr; | |
| 509 } | |
| 510 | |
| 511 ChannelSplitterNode* node = ChannelSplitterNode::create(*this, sampleRate(),
numberOfOutputs); | |
| 512 | |
| 513 if (!node) { | |
| 514 exceptionState.throwDOMException( | |
| 515 IndexSizeError, | |
| 516 "number of outputs (" + String::number(numberOfOutputs) | |
| 517 + ") must be between 1 and " | |
| 518 + String::number(AbstractAudioContext::maxNumberOfChannels()) + ".")
; | |
| 519 return nullptr; | |
| 520 } | |
| 521 | |
| 522 return node; | |
| 523 } | 399 } |
| 524 | 400 |
| 525 ChannelMergerNode* AbstractAudioContext::createChannelMerger(ExceptionState& exc
eptionState) | 401 ChannelMergerNode* AbstractAudioContext::createChannelMerger(ExceptionState& exc
eptionState) |
| 526 { | 402 { |
| 527 const unsigned ChannelMergerDefaultNumberOfInputs = 6; | 403 ASSERT(isMainThread()); |
| 528 return createChannelMerger(ChannelMergerDefaultNumberOfInputs, exceptionStat
e); | 404 |
| 405 return ChannelMergerNode::create(*this, exceptionState); |
| 529 } | 406 } |
| 530 | 407 |
| 531 ChannelMergerNode* AbstractAudioContext::createChannelMerger(size_t numberOfInpu
ts, ExceptionState& exceptionState) | 408 ChannelMergerNode* AbstractAudioContext::createChannelMerger(size_t numberOfInpu
ts, ExceptionState& exceptionState) |
| 532 { | 409 { |
| 533 ASSERT(isMainThread()); | 410 ASSERT(isMainThread()); |
| 534 if (isContextClosed()) { | |
| 535 throwExceptionForClosedState(exceptionState); | |
| 536 return nullptr; | |
| 537 } | |
| 538 | 411 |
| 539 ChannelMergerNode* node = ChannelMergerNode::create(*this, sampleRate(), num
berOfInputs); | 412 return ChannelMergerNode::create(*this, numberOfInputs, exceptionState); |
| 540 | |
| 541 if (!node) { | |
| 542 exceptionState.throwDOMException( | |
| 543 IndexSizeError, | |
| 544 ExceptionMessages::indexOutsideRange<size_t>( | |
| 545 "number of inputs", | |
| 546 numberOfInputs, | |
| 547 1, | |
| 548 ExceptionMessages::InclusiveBound, | |
| 549 AbstractAudioContext::maxNumberOfChannels(), | |
| 550 ExceptionMessages::InclusiveBound)); | |
| 551 return nullptr; | |
| 552 } | |
| 553 | |
| 554 return node; | |
| 555 } | 413 } |
| 556 | 414 |
| 557 OscillatorNode* AbstractAudioContext::createOscillator(ExceptionState& exception
State) | 415 OscillatorNode* AbstractAudioContext::createOscillator(ExceptionState& exception
State) |
| 558 { | 416 { |
| 559 ASSERT(isMainThread()); | 417 ASSERT(isMainThread()); |
| 560 if (isContextClosed()) { | |
| 561 throwExceptionForClosedState(exceptionState); | |
| 562 return nullptr; | |
| 563 } | |
| 564 | 418 |
| 565 OscillatorNode* node = OscillatorNode::create(*this, sampleRate()); | 419 return OscillatorNode::create(*this, exceptionState); |
| 566 | |
| 567 // Do not add a reference to this source node now. The reference will be add
ed when start() is | |
| 568 // called. | |
| 569 | |
| 570 return node; | |
| 571 } | 420 } |
| 572 | 421 |
| 573 PeriodicWave* AbstractAudioContext::createPeriodicWave(DOMFloat32Array* real, DO
MFloat32Array* imag, ExceptionState& exceptionState) | 422 PeriodicWave* AbstractAudioContext::createPeriodicWave(DOMFloat32Array* real, DO
MFloat32Array* imag, ExceptionState& exceptionState) |
| 574 { | 423 { |
| 575 return PeriodicWave::create(sampleRate(), real, imag, false); | 424 ASSERT(isMainThread()); |
| 425 |
| 426 return PeriodicWave::create(*this, real, imag, false, exceptionState); |
| 576 } | 427 } |
| 577 | 428 |
| 578 PeriodicWave* AbstractAudioContext::createPeriodicWave(DOMFloat32Array* real, DO
MFloat32Array* imag, const PeriodicWaveConstraints& options, ExceptionState& exc
eptionState) | 429 PeriodicWave* AbstractAudioContext::createPeriodicWave(DOMFloat32Array* real, DO
MFloat32Array* imag, const PeriodicWaveConstraints& options, ExceptionState& exc
eptionState) |
| 579 { | 430 { |
| 580 ASSERT(isMainThread()); | 431 ASSERT(isMainThread()); |
| 581 | 432 |
| 582 if (isContextClosed()) { | |
| 583 throwExceptionForClosedState(exceptionState); | |
| 584 return nullptr; | |
| 585 } | |
| 586 | |
| 587 if (real->length() != imag->length()) { | |
| 588 exceptionState.throwDOMException( | |
| 589 IndexSizeError, | |
| 590 "length of real array (" + String::number(real->length()) | |
| 591 + ") and length of imaginary array (" + String::number(imag->length
()) | |
| 592 + ") must match."); | |
| 593 return nullptr; | |
| 594 } | |
| 595 | |
| 596 bool disable = options.hasDisableNormalization() ? options.disableNormalizat
ion() : false; | 433 bool disable = options.hasDisableNormalization() ? options.disableNormalizat
ion() : false; |
| 597 | 434 |
| 598 return PeriodicWave::create(sampleRate(), real, imag, disable); | 435 return PeriodicWave::create(*this, real, imag, disable, exceptionState); |
| 599 } | 436 } |
| 600 | 437 |
| 601 IIRFilterNode* AbstractAudioContext::createIIRFilter(Vector<double> feedforwardC
oef, Vector<double> feedbackCoef, ExceptionState& exceptionState) | 438 IIRFilterNode* AbstractAudioContext::createIIRFilter(Vector<double> feedforwardC
oef, Vector<double> feedbackCoef, ExceptionState& exceptionState) |
| 602 { | 439 { |
| 603 ASSERT(isMainThread()); | 440 ASSERT(isMainThread()); |
| 604 | 441 |
| 605 if (isContextClosed()) { | 442 return IIRFilterNode::create(*this, feedforwardCoef, feedbackCoef, exception
State); |
| 606 throwExceptionForClosedState(exceptionState); | |
| 607 return nullptr; | |
| 608 } | |
| 609 | |
| 610 if (feedbackCoef.size() == 0 || (feedbackCoef.size() > IIRFilter::kMaxOrder
+ 1)) { | |
| 611 exceptionState.throwDOMException( | |
| 612 NotSupportedError, | |
| 613 ExceptionMessages::indexOutsideRange<size_t>( | |
| 614 "number of feedback coefficients", | |
| 615 feedbackCoef.size(), | |
| 616 1, | |
| 617 ExceptionMessages::InclusiveBound, | |
| 618 IIRFilter::kMaxOrder + 1, | |
| 619 ExceptionMessages::InclusiveBound)); | |
| 620 return nullptr; | |
| 621 } | |
| 622 | |
| 623 if (feedforwardCoef.size() == 0 || (feedforwardCoef.size() > IIRFilter::kMax
Order + 1)) { | |
| 624 exceptionState.throwDOMException( | |
| 625 NotSupportedError, | |
| 626 ExceptionMessages::indexOutsideRange<size_t>( | |
| 627 "number of feedforward coefficients", | |
| 628 feedforwardCoef.size(), | |
| 629 1, | |
| 630 ExceptionMessages::InclusiveBound, | |
| 631 IIRFilter::kMaxOrder + 1, | |
| 632 ExceptionMessages::InclusiveBound)); | |
| 633 return nullptr; | |
| 634 } | |
| 635 | |
| 636 if (feedbackCoef[0] == 0) { | |
| 637 exceptionState.throwDOMException( | |
| 638 InvalidStateError, | |
| 639 "First feedback coefficient cannot be zero."); | |
| 640 return nullptr; | |
| 641 } | |
| 642 | |
| 643 bool hasNonZeroCoef = false; | |
| 644 | |
| 645 for (size_t k = 0; k < feedforwardCoef.size(); ++k) { | |
| 646 if (feedforwardCoef[k] != 0) { | |
| 647 hasNonZeroCoef = true; | |
| 648 break; | |
| 649 } | |
| 650 } | |
| 651 | |
| 652 if (!hasNonZeroCoef) { | |
| 653 exceptionState.throwDOMException( | |
| 654 InvalidStateError, | |
| 655 "At least one feedforward coefficient must be non-zero."); | |
| 656 return nullptr; | |
| 657 } | |
| 658 | |
| 659 // Make sure all coefficents are finite. | |
| 660 for (size_t k = 0; k < feedforwardCoef.size(); ++k) { | |
| 661 double c = feedforwardCoef[k]; | |
| 662 if (!std::isfinite(c)) { | |
| 663 String name = "feedforward coefficient " + String::number(k); | |
| 664 exceptionState.throwDOMException( | |
| 665 InvalidStateError, | |
| 666 ExceptionMessages::notAFiniteNumber(c, name.ascii().data())); | |
| 667 return nullptr; | |
| 668 } | |
| 669 } | |
| 670 | |
| 671 for (size_t k = 0; k < feedbackCoef.size(); ++k) { | |
| 672 double c = feedbackCoef[k]; | |
| 673 if (!std::isfinite(c)) { | |
| 674 String name = "feedback coefficient " + String::number(k); | |
| 675 exceptionState.throwDOMException( | |
| 676 InvalidStateError, | |
| 677 ExceptionMessages::notAFiniteNumber(c, name.ascii().data())); | |
| 678 return nullptr; | |
| 679 } | |
| 680 } | |
| 681 | |
| 682 return IIRFilterNode::create(*this, sampleRate(), feedforwardCoef, feedbackC
oef); | |
| 683 } | 443 } |
| 684 | 444 |
| 685 PeriodicWave* AbstractAudioContext::periodicWave(int type) | 445 PeriodicWave* AbstractAudioContext::periodicWave(int type) |
| 686 { | 446 { |
| 687 switch (type) { | 447 switch (type) { |
| 688 case OscillatorHandler::SINE: | 448 case OscillatorHandler::SINE: |
| 689 // Initialize the table if necessary | 449 // Initialize the table if necessary |
| 690 if (!m_periodicWaveSine) | 450 if (!m_periodicWaveSine) |
| 691 m_periodicWaveSine = PeriodicWave::createSine(sampleRate()); | 451 m_periodicWaveSine = PeriodicWave::createSine(sampleRate()); |
| 692 return m_periodicWaveSine; | 452 return m_periodicWaveSine; |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 976 | 736 |
| 977 SecurityOrigin* AbstractAudioContext::getSecurityOrigin() const | 737 SecurityOrigin* AbstractAudioContext::getSecurityOrigin() const |
| 978 { | 738 { |
| 979 if (getExecutionContext()) | 739 if (getExecutionContext()) |
| 980 return getExecutionContext()->getSecurityOrigin(); | 740 return getExecutionContext()->getSecurityOrigin(); |
| 981 | 741 |
| 982 return nullptr; | 742 return nullptr; |
| 983 } | 743 } |
| 984 | 744 |
| 985 } // namespace blink | 745 } // namespace blink |
| OLD | NEW |