| 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 19 matching lines...) Expand all Loading... |
| 30 #include "platform/audio/AudioBus.h" | 30 #include "platform/audio/AudioBus.h" |
| 31 | 31 |
| 32 namespace blink { | 32 namespace blink { |
| 33 | 33 |
| 34 GainHandler::GainHandler(AudioNode& node, | 34 GainHandler::GainHandler(AudioNode& node, |
| 35 float sampleRate, | 35 float sampleRate, |
| 36 AudioParamHandler& gain) | 36 AudioParamHandler& gain) |
| 37 : AudioHandler(NodeTypeGain, node, sampleRate), | 37 : AudioHandler(NodeTypeGain, node, sampleRate), |
| 38 m_lastGain(1.0), | 38 m_lastGain(1.0), |
| 39 m_gain(gain), | 39 m_gain(gain), |
| 40 m_sampleAccurateGainValues( | 40 m_sampleAccurateGainValues(ProcessingSizeInFrames) // FIXME: can probably |
| 41 ProcessingSizeInFrames) // FIXME: can probably share temp buffer in c
ontext | 41 // share temp buffer |
| 42 // in context |
| 42 { | 43 { |
| 43 addInput(); | 44 addInput(); |
| 44 addOutput(1); | 45 addOutput(1); |
| 45 | 46 |
| 46 initialize(); | 47 initialize(); |
| 47 } | 48 } |
| 48 | 49 |
| 49 PassRefPtr<GainHandler> GainHandler::create(AudioNode& node, | 50 PassRefPtr<GainHandler> GainHandler::create(AudioNode& node, |
| 50 float sampleRate, | 51 float sampleRate, |
| 51 AudioParamHandler& gain) { | 52 AudioParamHandler& gain) { |
| 52 return adoptRef(new GainHandler(node, sampleRate, gain)); | 53 return adoptRef(new GainHandler(node, sampleRate, gain)); |
| 53 } | 54 } |
| 54 | 55 |
| 55 void GainHandler::process(size_t framesToProcess) { | 56 void GainHandler::process(size_t framesToProcess) { |
| 56 // FIXME: for some cases there is a nice optimization to avoid processing here
, and let the gain change | 57 // FIXME: for some cases there is a nice optimization to avoid processing |
| 57 // happen in the summing junction input of the AudioNode we're connected to. | 58 // here, and let the gain change happen in the summing junction input of the |
| 58 // Then we can avoid all of the following: | 59 // AudioNode we're connected to. Then we can avoid all of the following: |
| 59 | 60 |
| 60 AudioBus* outputBus = output(0).bus(); | 61 AudioBus* outputBus = output(0).bus(); |
| 61 DCHECK(outputBus); | 62 DCHECK(outputBus); |
| 62 | 63 |
| 63 if (!isInitialized() || !input(0).isConnected()) { | 64 if (!isInitialized() || !input(0).isConnected()) { |
| 64 outputBus->zero(); | 65 outputBus->zero(); |
| 65 } else { | 66 } else { |
| 66 AudioBus* inputBus = input(0).bus(); | 67 AudioBus* inputBus = input(0).bus(); |
| 67 | 68 |
| 68 if (m_gain->hasSampleAccurateValues()) { | 69 if (m_gain->hasSampleAccurateValues()) { |
| 69 // Apply sample-accurate gain scaling for precise envelopes, grain windows
, etc. | 70 // Apply sample-accurate gain scaling for precise envelopes, grain |
| 71 // windows, etc. |
| 70 DCHECK_LE(framesToProcess, m_sampleAccurateGainValues.size()); | 72 DCHECK_LE(framesToProcess, m_sampleAccurateGainValues.size()); |
| 71 if (framesToProcess <= m_sampleAccurateGainValues.size()) { | 73 if (framesToProcess <= m_sampleAccurateGainValues.size()) { |
| 72 float* gainValues = m_sampleAccurateGainValues.data(); | 74 float* gainValues = m_sampleAccurateGainValues.data(); |
| 73 m_gain->calculateSampleAccurateValues(gainValues, framesToProcess); | 75 m_gain->calculateSampleAccurateValues(gainValues, framesToProcess); |
| 74 outputBus->copyWithSampleAccurateGainValuesFrom(*inputBus, gainValues, | 76 outputBus->copyWithSampleAccurateGainValuesFrom(*inputBus, gainValues, |
| 75 framesToProcess); | 77 framesToProcess); |
| 76 // Update m_lastGain so if the timeline ever ends, we get | 78 // Update m_lastGain so if the timeline ever ends, we get |
| 77 // consistent data for the smoothing below. (Without this, | 79 // consistent data for the smoothing below. (Without this, |
| 78 // m_lastGain was the last value before the timeline started | 80 // m_lastGain was the last value before the timeline started |
| 79 // procesing. | 81 // procesing. |
| 80 m_lastGain = gainValues[framesToProcess - 1]; | 82 m_lastGain = gainValues[framesToProcess - 1]; |
| 81 } | 83 } |
| 82 } else { | 84 } else { |
| 83 // Apply the gain with de-zippering into the output bus. | 85 // Apply the gain with de-zippering into the output bus. |
| 84 if (!m_lastGain && m_lastGain == m_gain->value()) { | 86 if (!m_lastGain && m_lastGain == m_gain->value()) { |
| 85 // If the gain is 0 (and we've converged on dezippering), just zero the
bus and set | 87 // If the gain is 0 (and we've converged on dezippering), just zero the |
| 86 // the silence hint. | 88 // bus and set the silence hint. |
| 87 outputBus->zero(); | 89 outputBus->zero(); |
| 88 } else { | 90 } else { |
| 89 outputBus->copyWithGainFrom(*inputBus, &m_lastGain, m_gain->value()); | 91 outputBus->copyWithGainFrom(*inputBus, &m_lastGain, m_gain->value()); |
| 90 } | 92 } |
| 91 } | 93 } |
| 92 } | 94 } |
| 93 } | 95 } |
| 94 | 96 |
| 95 // FIXME: this can go away when we do mixing with gain directly in summing junct
ion of AudioNodeInput | 97 // FIXME: this can go away when we do mixing with gain directly in summing |
| 98 // junction of AudioNodeInput |
| 96 // | 99 // |
| 97 // As soon as we know the channel count of our input, we can lazily initialize. | 100 // As soon as we know the channel count of our input, we can lazily initialize. |
| 98 // Sometimes this may be called more than once with different channel counts, in
which case we must safely | 101 // Sometimes this may be called more than once with different channel counts, in |
| 99 // uninitialize and then re-initialize with the new channel count. | 102 // which case we must safely uninitialize and then re-initialize with the new |
| 103 // channel count. |
| 100 void GainHandler::checkNumberOfChannelsForInput(AudioNodeInput* input) { | 104 void GainHandler::checkNumberOfChannelsForInput(AudioNodeInput* input) { |
| 101 DCHECK(context()->isAudioThread()); | 105 DCHECK(context()->isAudioThread()); |
| 102 ASSERT(context()->isGraphOwner()); | 106 ASSERT(context()->isGraphOwner()); |
| 103 | 107 |
| 104 DCHECK(input); | 108 DCHECK(input); |
| 105 DCHECK_EQ(input, &this->input(0)); | 109 DCHECK_EQ(input, &this->input(0)); |
| 106 if (input != &this->input(0)) | 110 if (input != &this->input(0)) |
| 107 return; | 111 return; |
| 108 | 112 |
| 109 unsigned numberOfChannels = input->numberOfChannels(); | 113 unsigned numberOfChannels = input->numberOfChannels(); |
| 110 | 114 |
| 111 if (isInitialized() && numberOfChannels != output(0).numberOfChannels()) { | 115 if (isInitialized() && numberOfChannels != output(0).numberOfChannels()) { |
| 112 // We're already initialized but the channel count has changed. | 116 // We're already initialized but the channel count has changed. |
| 113 uninitialize(); | 117 uninitialize(); |
| 114 } | 118 } |
| 115 | 119 |
| 116 if (!isInitialized()) { | 120 if (!isInitialized()) { |
| 117 // This will propagate the channel count to any nodes connected further down
stream in the graph. | 121 // This will propagate the channel count to any nodes connected further |
| 122 // downstream in the graph. |
| 118 output(0).setNumberOfChannels(numberOfChannels); | 123 output(0).setNumberOfChannels(numberOfChannels); |
| 119 initialize(); | 124 initialize(); |
| 120 } | 125 } |
| 121 | 126 |
| 122 AudioHandler::checkNumberOfChannelsForInput(input); | 127 AudioHandler::checkNumberOfChannelsForInput(input); |
| 123 } | 128 } |
| 124 | 129 |
| 125 // ---------------------------------------------------------------- | 130 // ---------------------------------------------------------------- |
| 126 | 131 |
| 127 GainNode::GainNode(BaseAudioContext& context) | 132 GainNode::GainNode(BaseAudioContext& context) |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 AudioParam* GainNode::gain() const { | 167 AudioParam* GainNode::gain() const { |
| 163 return m_gain; | 168 return m_gain; |
| 164 } | 169 } |
| 165 | 170 |
| 166 DEFINE_TRACE(GainNode) { | 171 DEFINE_TRACE(GainNode) { |
| 167 visitor->trace(m_gain); | 172 visitor->trace(m_gain); |
| 168 AudioNode::trace(visitor); | 173 AudioNode::trace(visitor); |
| 169 } | 174 } |
| 170 | 175 |
| 171 } // namespace blink | 176 } // namespace blink |
| OLD | NEW |