| 350 | |
| 351 | |
| 352 | static void Engine_stepFrameCables(Engine* that) { |
| 353 | auto finitize = [](float x) { |
| 354 | return std::isfinite(x) ? x : 0.f; |
| 355 | }; |
| 356 | |
| 357 | // Iterate each cable input group, since `cables` is sorted by input |
| 358 | auto firstIt = that->internal->cables.begin(); |
| 359 | while (firstIt != that->internal->cables.end()) { |
| 360 | Cable* firstCable = *firstIt; |
| 361 | Input* input = &firstCable->inputModule->inputs[firstCable->inputId]; |
| 362 | |
| 363 | // Find end of input group |
| 364 | auto endIt = firstIt; |
| 365 | while (++endIt != that->internal->cables.end()) { |
| 366 | Cable* endCable = *endIt; |
| 367 | // Check inputId first since it changes more frequently between cables |
| 368 | if (!(endCable->inputId == firstCable->inputId && endCable->inputModule == firstCable->inputModule)) |
| 369 | break; |
| 370 | } |
| 371 | |
| 372 | // Since stackable inputs are uncommon, only use stackable input logic if there are multiple cables in input group. |
| 373 | if (endIt - firstIt == 1) { |
| 374 | Output* output = &firstCable->outputModule->outputs[firstCable->outputId]; |
| 375 | // Copy all voltages from output to input |
| 376 | for (uint8_t c = 0; c < output->channels; c++) { |
| 377 | input->voltages[c] = finitize(output->voltages[c]); |
| 378 | } |
| 379 | // Set higher channel voltages to 0 |
| 380 | for (uint8_t c = output->channels; c < input->channels; c++) { |
| 381 | input->voltages[c] = 0.f; |
| 382 | } |
| 383 | input->channels = output->channels; |
| 384 | } |
| 385 | else { |
| 386 | // Calculate max output channels |
| 387 | uint8_t channels = 0; |
| 388 | for (auto it = firstIt; it < endIt; ++it) { |
| 389 | Cable* cable = *it; |
| 390 | Output* output = &cable->outputModule->outputs[cable->outputId]; |
| 391 | channels = std::max(channels, output->channels); |
| 392 | } |
| 393 | |
| 394 | // Clear input channels, including old channels |
| 395 | for (uint8_t c = 0; c < std::max(channels, input->channels); c++) { |
| 396 | input->voltages[c] = 0.f; |
| 397 | } |
| 398 | input->channels = channels; |
| 399 | |
| 400 | // Sum outputs of cables |
| 401 | for (auto it = firstIt; it < endIt; ++it) { |
| 402 | Cable* cable = *it; |
| 403 | Output* output = &cable->outputModule->outputs[cable->outputId]; |
| 404 | |
| 405 | // Sum monophonic value to all input channels |
| 406 | if (output->channels == 1) { |
| 407 | float value = finitize(output->voltages[0]); |
| 408 | for (uint8_t c = 0; c < channels; c++) { |
| 409 | input->voltages[c] += value; |
no test coverage detected