GainNode.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /*
  2. * Copyright (C) 2010, Google Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  15. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  16. * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
  17. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  18. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  19. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  20. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  21. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  22. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23. */
  24. #include "config.h"
  25. #if ENABLE(WEB_AUDIO)
  26. #include "GainNode.h"
  27. #include "AudioBus.h"
  28. #include "AudioNodeInput.h"
  29. #include "AudioNodeOutput.h"
  30. namespace WebCore {
  31. GainNode::GainNode(AudioContext* context, float sampleRate)
  32. : AudioNode(context, sampleRate)
  33. , m_lastGain(1.0)
  34. , m_sampleAccurateGainValues(AudioNode::ProcessingSizeInFrames) // FIXME: can probably share temp buffer in context
  35. {
  36. m_gain = AudioParam::create(context, "gain", 1.0, 0.0, 1.0);
  37. addInput(adoptPtr(new AudioNodeInput(this)));
  38. addOutput(adoptPtr(new AudioNodeOutput(this, 1)));
  39. setNodeType(NodeTypeGain);
  40. initialize();
  41. }
  42. void GainNode::process(size_t framesToProcess)
  43. {
  44. // FIXME: for some cases there is a nice optimization to avoid processing here, and let the gain change
  45. // happen in the summing junction input of the AudioNode we're connected to.
  46. // Then we can avoid all of the following:
  47. AudioBus* outputBus = output(0)->bus();
  48. ASSERT(outputBus);
  49. if (!isInitialized() || !input(0)->isConnected())
  50. outputBus->zero();
  51. else {
  52. AudioBus* inputBus = input(0)->bus();
  53. if (gain()->hasSampleAccurateValues()) {
  54. // Apply sample-accurate gain scaling for precise envelopes, grain windows, etc.
  55. ASSERT(framesToProcess <= m_sampleAccurateGainValues.size());
  56. if (framesToProcess <= m_sampleAccurateGainValues.size()) {
  57. float* gainValues = m_sampleAccurateGainValues.data();
  58. gain()->calculateSampleAccurateValues(gainValues, framesToProcess);
  59. outputBus->copyWithSampleAccurateGainValuesFrom(*inputBus, gainValues, framesToProcess);
  60. }
  61. } else {
  62. // Apply the gain with de-zippering into the output bus.
  63. outputBus->copyWithGainFrom(*inputBus, &m_lastGain, gain()->value());
  64. }
  65. }
  66. }
  67. void GainNode::reset()
  68. {
  69. // Snap directly to desired gain.
  70. m_lastGain = gain()->value();
  71. }
  72. // FIXME: this can go away when we do mixing with gain directly in summing junction of AudioNodeInput
  73. //
  74. // As soon as we know the channel count of our input, we can lazily initialize.
  75. // Sometimes this may be called more than once with different channel counts, in which case we must safely
  76. // uninitialize and then re-initialize with the new channel count.
  77. void GainNode::checkNumberOfChannelsForInput(AudioNodeInput* input)
  78. {
  79. ASSERT(context()->isAudioThread() && context()->isGraphOwner());
  80. ASSERT(input && input == this->input(0));
  81. if (input != this->input(0))
  82. return;
  83. unsigned numberOfChannels = input->numberOfChannels();
  84. if (isInitialized() && numberOfChannels != output(0)->numberOfChannels()) {
  85. // We're already initialized but the channel count has changed.
  86. uninitialize();
  87. }
  88. if (!isInitialized()) {
  89. // This will propagate the channel count to any nodes connected further downstream in the graph.
  90. output(0)->setNumberOfChannels(numberOfChannels);
  91. initialize();
  92. }
  93. AudioNode::checkNumberOfChannelsForInput(input);
  94. }
  95. } // namespace WebCore
  96. #endif // ENABLE(WEB_AUDIO)