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 |