| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011, Google Inc. All rights reserved. | 2 * Copyright (C) 2011, 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 13 matching lines...) Expand all Loading... |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include "modules/webaudio/OfflineAudioDestinationNode.h" | 26 #include "modules/webaudio/OfflineAudioDestinationNode.h" |
| 27 | 27 |
| 28 #include "core/dom/ExecutionContextTask.h" | 28 #include "core/dom/ExecutionContextTask.h" |
| 29 #include "modules/webaudio/AudioNodeInput.h" | 29 #include "modules/webaudio/AudioNodeInput.h" |
| 30 #include "modules/webaudio/AudioNodeOutput.h" | 30 #include "modules/webaudio/AudioNodeOutput.h" |
| 31 #include "modules/webaudio/BaseAudioContext.h" | 31 #include "modules/webaudio/BaseAudioContext.h" |
| 32 #include "modules/webaudio/OfflineAudioContext.h" | 32 #include "modules/webaudio/OfflineAudioContext.h" |
| 33 #include "platform/audio/AudioBus.h" | 33 #include "platform/audio/AudioBus.h" |
| 34 #include "platform/audio/AudioUtilities.h" |
| 34 #include "platform/audio/DenormalDisabler.h" | 35 #include "platform/audio/DenormalDisabler.h" |
| 35 #include "platform/audio/HRTFDatabaseLoader.h" | 36 #include "platform/audio/HRTFDatabaseLoader.h" |
| 36 #include "public/platform/Platform.h" | 37 #include "public/platform/Platform.h" |
| 37 #include "wtf/PtrUtil.h" | 38 #include "wtf/PtrUtil.h" |
| 38 #include <algorithm> | 39 #include <algorithm> |
| 39 | 40 |
| 40 namespace blink { | 41 namespace blink { |
| 41 | 42 |
| 42 const size_t OfflineAudioDestinationHandler::renderQuantumSize = 128; | |
| 43 | |
| 44 OfflineAudioDestinationHandler::OfflineAudioDestinationHandler( | 43 OfflineAudioDestinationHandler::OfflineAudioDestinationHandler( |
| 45 AudioNode& node, | 44 AudioNode& node, |
| 46 AudioBuffer* renderTarget) | 45 AudioBuffer* renderTarget) |
| 47 : AudioDestinationHandler(node, renderTarget->sampleRate()), | 46 : AudioDestinationHandler(node, renderTarget->sampleRate()), |
| 48 m_renderTarget(renderTarget), | 47 m_renderTarget(renderTarget), |
| 49 m_renderThread(wrapUnique( | 48 m_renderThread(wrapUnique( |
| 50 Platform::current()->createThread("offline audio renderer"))), | 49 Platform::current()->createThread("offline audio renderer"))), |
| 51 m_framesProcessed(0), | 50 m_framesProcessed(0), |
| 52 m_framesToProcess(0), | 51 m_framesToProcess(0), |
| 53 m_isRenderingStarted(false), | 52 m_isRenderingStarted(false), |
| 54 m_shouldSuspend(false) { | 53 m_shouldSuspend(false) { |
| 55 m_renderBus = | 54 m_renderBus = AudioBus::create(renderTarget->numberOfChannels(), |
| 56 AudioBus::create(renderTarget->numberOfChannels(), renderQuantumSize); | 55 AudioUtilities::kRenderQuantumFrames); |
| 57 m_framesToProcess = m_renderTarget->length(); | 56 m_framesToProcess = m_renderTarget->length(); |
| 58 | 57 |
| 59 // Node-specific defaults. | 58 // Node-specific defaults. |
| 60 m_channelCount = m_renderTarget->numberOfChannels(); | 59 m_channelCount = m_renderTarget->numberOfChannels(); |
| 61 setInternalChannelCountMode(Explicit); | 60 setInternalChannelCountMode(Explicit); |
| 62 setInternalChannelInterpretation(AudioBus::Speakers); | 61 setInternalChannelInterpretation(AudioBus::Speakers); |
| 63 } | 62 } |
| 64 | 63 |
| 65 PassRefPtr<OfflineAudioDestinationHandler> | 64 PassRefPtr<OfflineAudioDestinationHandler> |
| 66 OfflineAudioDestinationHandler::create(AudioNode& node, | 65 OfflineAudioDestinationHandler::create(AudioNode& node, |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 DCHECK(isAudioContextInitialized); | 149 DCHECK(isAudioContextInitialized); |
| 151 if (!isAudioContextInitialized) | 150 if (!isAudioContextInitialized) |
| 152 return; | 151 return; |
| 153 | 152 |
| 154 bool channelsMatch = | 153 bool channelsMatch = |
| 155 m_renderBus->numberOfChannels() == m_renderTarget->numberOfChannels(); | 154 m_renderBus->numberOfChannels() == m_renderTarget->numberOfChannels(); |
| 156 DCHECK(channelsMatch); | 155 DCHECK(channelsMatch); |
| 157 if (!channelsMatch) | 156 if (!channelsMatch) |
| 158 return; | 157 return; |
| 159 | 158 |
| 160 bool isRenderBusAllocated = m_renderBus->length() >= renderQuantumSize; | 159 bool isRenderBusAllocated = |
| 160 m_renderBus->length() >= AudioUtilities::kRenderQuantumFrames; |
| 161 DCHECK(isRenderBusAllocated); | 161 DCHECK(isRenderBusAllocated); |
| 162 if (!isRenderBusAllocated) | 162 if (!isRenderBusAllocated) |
| 163 return; | 163 return; |
| 164 | 164 |
| 165 // Start rendering. | 165 // Start rendering. |
| 166 doOfflineRendering(); | 166 doOfflineRendering(); |
| 167 } | 167 } |
| 168 | 168 |
| 169 void OfflineAudioDestinationHandler::doOfflineRendering() { | 169 void OfflineAudioDestinationHandler::doOfflineRendering() { |
| 170 DCHECK(!isMainThread()); | 170 DCHECK(!isMainThread()); |
| 171 | 171 |
| 172 unsigned numberOfChannels = m_renderTarget->numberOfChannels(); | 172 unsigned numberOfChannels = m_renderTarget->numberOfChannels(); |
| 173 | 173 |
| 174 // Reset the suspend flag. | 174 // Reset the suspend flag. |
| 175 m_shouldSuspend = false; | 175 m_shouldSuspend = false; |
| 176 | 176 |
| 177 // If there is more to process and there is no suspension at the moment, | 177 // If there is more to process and there is no suspension at the moment, |
| 178 // do continue to render quanta. Then calling OfflineAudioContext.resume() | 178 // do continue to render quanta. Then calling OfflineAudioContext.resume() |
| 179 // will pick up the render loop again from where it was suspended. | 179 // will pick up the render loop again from where it was suspended. |
| 180 while (m_framesToProcess > 0 && !m_shouldSuspend) { | 180 while (m_framesToProcess > 0 && !m_shouldSuspend) { |
| 181 // Suspend the rendering and update m_shouldSuspend if a scheduled | 181 // Suspend the rendering and update m_shouldSuspend if a scheduled |
| 182 // suspend found at the current sample frame. Otherwise render one | 182 // suspend found at the current sample frame. Otherwise render one |
| 183 // quantum and return false. | 183 // quantum and return false. |
| 184 m_shouldSuspend = | 184 m_shouldSuspend = renderIfNotSuspended( |
| 185 renderIfNotSuspended(0, m_renderBus.get(), renderQuantumSize); | 185 0, m_renderBus.get(), AudioUtilities::kRenderQuantumFrames); |
| 186 | 186 |
| 187 if (m_shouldSuspend) | 187 if (m_shouldSuspend) |
| 188 return; | 188 return; |
| 189 | 189 |
| 190 size_t framesAvailableToCopy = | 190 size_t framesAvailableToCopy = |
| 191 std::min(m_framesToProcess, renderQuantumSize); | 191 std::min(m_framesToProcess, |
| 192 static_cast<size_t>(AudioUtilities::kRenderQuantumFrames)); |
| 192 | 193 |
| 193 for (unsigned channelIndex = 0; channelIndex < numberOfChannels; | 194 for (unsigned channelIndex = 0; channelIndex < numberOfChannels; |
| 194 ++channelIndex) { | 195 ++channelIndex) { |
| 195 const float* source = m_renderBus->channel(channelIndex)->data(); | 196 const float* source = m_renderBus->channel(channelIndex)->data(); |
| 196 float* destination = m_renderTarget->getChannelData(channelIndex)->data(); | 197 float* destination = m_renderTarget->getChannelData(channelIndex)->data(); |
| 197 memcpy(destination + m_framesProcessed, source, | 198 memcpy(destination + m_framesProcessed, source, |
| 198 sizeof(float) * framesAvailableToCopy); | 199 sizeof(float) * framesAvailableToCopy); |
| 199 } | 200 } |
| 200 | 201 |
| 201 m_framesProcessed += framesAvailableToCopy; | 202 m_framesProcessed += framesAvailableToCopy; |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 setHandler(OfflineAudioDestinationHandler::create(*this, renderTarget)); | 330 setHandler(OfflineAudioDestinationHandler::create(*this, renderTarget)); |
| 330 } | 331 } |
| 331 | 332 |
| 332 OfflineAudioDestinationNode* OfflineAudioDestinationNode::create( | 333 OfflineAudioDestinationNode* OfflineAudioDestinationNode::create( |
| 333 BaseAudioContext* context, | 334 BaseAudioContext* context, |
| 334 AudioBuffer* renderTarget) { | 335 AudioBuffer* renderTarget) { |
| 335 return new OfflineAudioDestinationNode(*context, renderTarget); | 336 return new OfflineAudioDestinationNode(*context, renderTarget); |
| 336 } | 337 } |
| 337 | 338 |
| 338 } // namespace blink | 339 } // namespace blink |
| OLD | NEW |