| 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 are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "config.h" | 31 #include "config.h" |
| 32 | 32 |
| 33 #if ENABLE(WEB_AUDIO) | 33 #if ENABLE(WEB_AUDIO) |
| 34 | 34 |
| 35 #include "core/platform/audio/AudioDSPKernelProcessor.h" | 35 #include "core/platform/audio/AudioDSPKernelProcessor.h" |
| 36 | 36 |
| 37 #include "core/platform/audio/AudioDSPKernel.h" | 37 #include "core/platform/audio/AudioDSPKernel.h" |
| 38 #include "wtf/MainThread.h" |
| 38 | 39 |
| 39 namespace WebCore { | 40 namespace WebCore { |
| 40 | 41 |
| 41 // setNumberOfChannels() may later be called if the object is not yet in an "ini
tialized" state. | 42 // setNumberOfChannels() may later be called if the object is not yet in an "ini
tialized" state. |
| 42 AudioDSPKernelProcessor::AudioDSPKernelProcessor(float sampleRate, unsigned numb
erOfChannels) | 43 AudioDSPKernelProcessor::AudioDSPKernelProcessor(float sampleRate, unsigned numb
erOfChannels) |
| 43 : AudioProcessor(sampleRate, numberOfChannels) | 44 : AudioProcessor(sampleRate, numberOfChannels) |
| 44 , m_hasJustReset(true) | 45 , m_hasJustReset(true) |
| 45 { | 46 { |
| 46 } | 47 } |
| 47 | 48 |
| 48 void AudioDSPKernelProcessor::initialize() | 49 void AudioDSPKernelProcessor::initialize() |
| 49 { | 50 { |
| 50 if (isInitialized()) | 51 if (isInitialized()) |
| 51 return; | 52 return; |
| 52 | 53 |
| 54 MutexLocker locker(m_processLock); |
| 53 ASSERT(!m_kernels.size()); | 55 ASSERT(!m_kernels.size()); |
| 54 | 56 |
| 55 // Create processing kernels, one per channel. | 57 // Create processing kernels, one per channel. |
| 56 for (unsigned i = 0; i < numberOfChannels(); ++i) | 58 for (unsigned i = 0; i < numberOfChannels(); ++i) |
| 57 m_kernels.append(createKernel()); | 59 m_kernels.append(createKernel()); |
| 58 | 60 |
| 59 m_initialized = true; | 61 m_initialized = true; |
| 60 m_hasJustReset = true; | 62 m_hasJustReset = true; |
| 61 } | 63 } |
| 62 | 64 |
| 63 void AudioDSPKernelProcessor::uninitialize() | 65 void AudioDSPKernelProcessor::uninitialize() |
| 64 { | 66 { |
| 65 if (!isInitialized()) | 67 if (!isInitialized()) |
| 66 return; | 68 return; |
| 67 | 69 |
| 70 MutexLocker locker(m_processLock); |
| 68 m_kernels.clear(); | 71 m_kernels.clear(); |
| 69 | 72 |
| 70 m_initialized = false; | 73 m_initialized = false; |
| 71 } | 74 } |
| 72 | 75 |
| 73 void AudioDSPKernelProcessor::process(const AudioBus* source, AudioBus* destinat
ion, size_t framesToProcess) | 76 void AudioDSPKernelProcessor::process(const AudioBus* source, AudioBus* destinat
ion, size_t framesToProcess) |
| 74 { | 77 { |
| 75 ASSERT(source && destination); | 78 ASSERT(source && destination); |
| 76 if (!source || !destination) | 79 if (!source || !destination) |
| 77 return; | 80 return; |
| 78 | 81 |
| 79 if (!isInitialized()) { | 82 if (!isInitialized()) { |
| 80 destination->zero(); | 83 destination->zero(); |
| 81 return; | 84 return; |
| 82 } | 85 } |
| 83 | 86 |
| 84 bool channelCountMatches = source->numberOfChannels() == destination->number
OfChannels() && source->numberOfChannels() == m_kernels.size(); | 87 MutexTryLocker tryLocker(m_processLock); |
| 85 ASSERT(channelCountMatches); | 88 if (tryLocker.locked()) { |
| 86 if (!channelCountMatches) | 89 bool channelCountMatches = source->numberOfChannels() == destination->nu
mberOfChannels() && source->numberOfChannels() == m_kernels.size(); |
| 87 return; | 90 ASSERT(channelCountMatches); |
| 91 if (!channelCountMatches) |
| 92 return; |
| 88 | 93 |
| 89 for (unsigned i = 0; i < m_kernels.size(); ++i) | 94 for (unsigned i = 0; i < m_kernels.size(); ++i) |
| 90 m_kernels[i]->process(source->channel(i)->data(), destination->channel(i
)->mutableData(), framesToProcess); | 95 m_kernels[i]->process(source->channel(i)->data(), destination->chann
el(i)->mutableData(), framesToProcess); |
| 96 } else { |
| 97 // Unfortunately, the kernel is being processed by another thread. |
| 98 // See also ConvolverNode::process(). |
| 99 destination->zero(); |
| 100 } |
| 91 } | 101 } |
| 92 | 102 |
| 93 // Resets filter state | 103 // Resets filter state |
| 94 void AudioDSPKernelProcessor::reset() | 104 void AudioDSPKernelProcessor::reset() |
| 95 { | 105 { |
| 106 ASSERT(isMainThread()); |
| 96 if (!isInitialized()) | 107 if (!isInitialized()) |
| 97 return; | 108 return; |
| 98 | 109 |
| 99 // Forces snap to parameter values - first time. | 110 // Forces snap to parameter values - first time. |
| 100 // Any processing depending on this value must set it to false at the approp
riate time. | 111 // Any processing depending on this value must set it to false at the approp
riate time. |
| 101 m_hasJustReset = true; | 112 m_hasJustReset = true; |
| 102 | 113 |
| 114 MutexLocker locker(m_processLock); |
| 103 for (unsigned i = 0; i < m_kernels.size(); ++i) | 115 for (unsigned i = 0; i < m_kernels.size(); ++i) |
| 104 m_kernels[i]->reset(); | 116 m_kernels[i]->reset(); |
| 105 } | 117 } |
| 106 | 118 |
| 107 void AudioDSPKernelProcessor::setNumberOfChannels(unsigned numberOfChannels) | 119 void AudioDSPKernelProcessor::setNumberOfChannels(unsigned numberOfChannels) |
| 108 { | 120 { |
| 109 if (numberOfChannels == m_numberOfChannels) | 121 if (numberOfChannels == m_numberOfChannels) |
| 110 return; | 122 return; |
| 111 | 123 |
| 112 ASSERT(!isInitialized()); | 124 ASSERT(!isInitialized()); |
| 113 if (!isInitialized()) | 125 if (!isInitialized()) |
| 114 m_numberOfChannels = numberOfChannels; | 126 m_numberOfChannels = numberOfChannels; |
| 115 } | 127 } |
| 116 | 128 |
| 117 double AudioDSPKernelProcessor::tailTime() const | 129 double AudioDSPKernelProcessor::tailTime() const |
| 118 { | 130 { |
| 119 // It is expected that all the kernels have the same tailTime. | 131 ASSERT(!isMainThread()); |
| 120 return !m_kernels.isEmpty() ? m_kernels.first()->tailTime() : 0; | 132 MutexTryLocker tryLocker(m_processLock); |
| 133 if (tryLocker.locked()) { |
| 134 // It is expected that all the kernels have the same tailTime. |
| 135 return !m_kernels.isEmpty() ? m_kernels.first()->tailTime() : 0; |
| 136 } |
| 137 // Since we don't want to block the Audio Device thread, we return a large v
alue |
| 138 // instead of trying to acquire the lock. |
| 139 return std::numeric_limits<double>::infinity(); |
| 121 } | 140 } |
| 122 | 141 |
| 123 double AudioDSPKernelProcessor::latencyTime() const | 142 double AudioDSPKernelProcessor::latencyTime() const |
| 124 { | 143 { |
| 125 // It is expected that all the kernels have the same latencyTime. | 144 ASSERT(!isMainThread()); |
| 126 return !m_kernels.isEmpty() ? m_kernels.first()->latencyTime() : 0; | 145 MutexTryLocker tryLocker(m_processLock); |
| 146 if (tryLocker.locked()) { |
| 147 // It is expected that all the kernels have the same latencyTime. |
| 148 return !m_kernels.isEmpty() ? m_kernels.first()->latencyTime() : 0; |
| 149 } |
| 150 // Since we don't want to block the Audio Device thread, we return a large v
alue |
| 151 // instead of trying to acquire the lock. |
| 152 return std::numeric_limits<double>::infinity(); |
| 127 } | 153 } |
| 128 | 154 |
| 129 } // namespace WebCore | 155 } // namespace WebCore |
| 130 | 156 |
| 131 #endif // ENABLE(WEB_AUDIO) | 157 #endif // ENABLE(WEB_AUDIO) |
| OLD | NEW |