| 269 | } |
| 270 | |
| 271 | void AudioContext::handlePreRenderTasks(ContextRenderLock & r) |
| 272 | { |
| 273 | // these may be null during application exit. |
| 274 | if (!r.context() || !m_audioContextInterface) |
| 275 | return; |
| 276 | |
| 277 | // At the beginning of every render quantum, update the graph. |
| 278 | |
| 279 | m_audioContextInterface->_currentTime = currentTime(); |
| 280 | |
| 281 | // check for pending connections |
| 282 | if (m_internal->pendingParamConnections.size_approx() > 0 || |
| 283 | m_internal->pendingNodeConnections.size_approx() > 0) |
| 284 | { |
| 285 | // take a graph lock until the queues are cleared |
| 286 | ContextGraphLock gLock(this, "AudioContext::handlePreRenderTasks()"); |
| 287 | |
| 288 | // resolve parameter connections |
| 289 | PendingParamConnection param_connection; |
| 290 | while (m_internal->pendingParamConnections.try_dequeue(param_connection)) |
| 291 | { |
| 292 | if (param_connection.type == ConnectionOperationKind::Connect) |
| 293 | { |
| 294 | AudioParam::connect(gLock, |
| 295 | param_connection.destination, |
| 296 | param_connection.source->output(param_connection.destIndex)); |
| 297 | |
| 298 | // if unscheduled, the source should start to play as soon as possible |
| 299 | if (!param_connection.source->isScheduledNode()) |
| 300 | param_connection.source->_scheduler.start(0); |
| 301 | } |
| 302 | else |
| 303 | AudioParam::disconnect(gLock, |
| 304 | param_connection.destination, |
| 305 | param_connection.source->output(param_connection.destIndex)); |
| 306 | } |
| 307 | |
| 308 | // resolve node connections |
| 309 | PendingNodeConnection node_connection; |
| 310 | std::vector<PendingNodeConnection> requeued_connections; |
| 311 | while (m_internal->pendingNodeConnections.try_dequeue(node_connection)) |
| 312 | { |
| 313 | switch (node_connection.type) |
| 314 | { |
| 315 | case ConnectionOperationKind::Connect: |
| 316 | { |
| 317 | AudioNodeInput::connect(gLock, |
| 318 | node_connection.destination->input(node_connection.destIndex), |
| 319 | node_connection.source->output(node_connection.srcIndex)); |
| 320 | |
| 321 | if (!node_connection.source->isScheduledNode()) |
| 322 | node_connection.source->_scheduler.start(0); |
| 323 | } |
| 324 | break; |
| 325 | |
| 326 | case ConnectionOperationKind::Disconnect: |
| 327 | { |
| 328 | node_connection.type = ConnectionOperationKind::FinishDisconnect; |
no test coverage detected