summaryrefslogtreecommitdiff
path: root/src/audio_core/splitter_context.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio_core/splitter_context.cpp')
-rw-r--r--src/audio_core/splitter_context.cpp60
1 files changed, 29 insertions, 31 deletions
diff --git a/src/audio_core/splitter_context.cpp b/src/audio_core/splitter_context.cpp
index f3e870648..f21b53147 100644
--- a/src/audio_core/splitter_context.cpp
+++ b/src/audio_core/splitter_context.cpp
@@ -109,7 +109,7 @@ std::size_t ServerSplitterInfo::Update(SplitterInfo::InInfoPrams& header) {
109 new_connection = true; 109 new_connection = true;
110 // We need to update the size here due to the splitter bug being present and providing an 110 // We need to update the size here due to the splitter bug being present and providing an
111 // incorrect size. We're suppose to also update the header here but we just ignore and continue 111 // incorrect size. We're suppose to also update the header here but we just ignore and continue
112 return (sizeof(s32_le) * static_cast<size_t>(header.length - 1)) + (sizeof(s32_le) * 3); 112 return (sizeof(s32_le) * (header.length - 1)) + (sizeof(s32_le) * 3);
113} 113}
114 114
115ServerSplitterDestinationData* ServerSplitterInfo::GetHead() { 115ServerSplitterDestinationData* ServerSplitterInfo::GetHead() {
@@ -306,14 +306,13 @@ bool SplitterContext::UpdateInfo(const std::vector<u8>& input, std::size_t& inpu
306 break; 306 break;
307 } 307 }
308 308
309 const auto send_id = static_cast<std::size_t>(header.send_id); 309 if (header.send_id < 0 || static_cast<std::size_t>(header.send_id) > info_count) {
310 if (header.send_id < 0 || send_id > info_count) {
311 LOG_ERROR(Audio, "Bad splitter data id"); 310 LOG_ERROR(Audio, "Bad splitter data id");
312 break; 311 break;
313 } 312 }
314 313
315 UpdateOffsets(sizeof(SplitterInfo::InInfoPrams)); 314 UpdateOffsets(sizeof(SplitterInfo::InInfoPrams));
316 auto& info = GetInfo(send_id); 315 auto& info = GetInfo(header.send_id);
317 if (!RecomposeDestination(info, header, input, input_offset)) { 316 if (!RecomposeDestination(info, header, input, input_offset)) {
318 LOG_ERROR(Audio, "Failed to recompose destination for splitter!"); 317 LOG_ERROR(Audio, "Failed to recompose destination for splitter!");
319 return false; 318 return false;
@@ -349,12 +348,11 @@ bool SplitterContext::UpdateData(const std::vector<u8>& input, std::size_t& inpu
349 break; 348 break;
350 } 349 }
351 350
352 const auto splitter_id = static_cast<std::size_t>(header.splitter_id); 351 if (header.splitter_id < 0 || static_cast<std::size_t>(header.splitter_id) > data_count) {
353 if (header.splitter_id < 0 || splitter_id > data_count) {
354 LOG_ERROR(Audio, "Bad splitter data id"); 352 LOG_ERROR(Audio, "Bad splitter data id");
355 break; 353 break;
356 } 354 }
357 GetData(splitter_id).Update(header); 355 GetData(header.splitter_id).Update(header);
358 } 356 }
359 return true; 357 return true;
360} 358}
@@ -388,9 +386,9 @@ bool SplitterContext::RecomposeDestination(ServerSplitterInfo& info,
388 return true; 386 return true;
389 } 387 }
390 388
391 auto* start_head = &GetData(static_cast<u32>(header.resource_id_base)); 389 auto* start_head = &GetData(header.resource_id_base);
392 current_head = start_head; 390 current_head = start_head;
393 std::vector<s32_le> resource_ids(static_cast<size_t>(size - 1)); 391 std::vector<s32_le> resource_ids(size - 1);
394 if (!AudioCommon::CanConsumeBuffer(input.size(), input_offset, 392 if (!AudioCommon::CanConsumeBuffer(input.size(), input_offset,
395 resource_ids.size() * sizeof(s32_le))) { 393 resource_ids.size() * sizeof(s32_le))) {
396 LOG_ERROR(Audio, "Buffer is an invalid size!"); 394 LOG_ERROR(Audio, "Buffer is an invalid size!");
@@ -399,8 +397,8 @@ bool SplitterContext::RecomposeDestination(ServerSplitterInfo& info,
399 std::memcpy(resource_ids.data(), input.data() + input_offset, 397 std::memcpy(resource_ids.data(), input.data() + input_offset,
400 resource_ids.size() * sizeof(s32_le)); 398 resource_ids.size() * sizeof(s32_le));
401 399
402 for (const auto resource_id : resource_ids) { 400 for (auto resource_id : resource_ids) {
403 auto* head = &GetData(static_cast<u32>(resource_id)); 401 auto* head = &GetData(resource_id);
404 current_head->SetNextDestination(head); 402 current_head->SetNextDestination(head);
405 current_head = head; 403 current_head = head;
406 } 404 }
@@ -446,7 +444,7 @@ bool NodeStates::DepthFirstSearch(EdgeMatrix& edge_matrix) {
446 const auto node_id = static_cast<s32>(i); 444 const auto node_id = static_cast<s32>(i);
447 445
448 // If we don't have a state, send to our index stack for work 446 // If we don't have a state, send to our index stack for work
449 if (GetState(i) == State::NoState) { 447 if (GetState(i) == NodeStates::State::NoState) {
450 index_stack.push(node_id); 448 index_stack.push(node_id);
451 } 449 }
452 450
@@ -455,19 +453,19 @@ bool NodeStates::DepthFirstSearch(EdgeMatrix& edge_matrix) {
455 // Get the current node 453 // Get the current node
456 const auto current_stack_index = index_stack.top(); 454 const auto current_stack_index = index_stack.top();
457 // Check if we've seen the node yet 455 // Check if we've seen the node yet
458 const auto index_state = GetState(static_cast<u32>(current_stack_index)); 456 const auto index_state = GetState(current_stack_index);
459 if (index_state == State::NoState) { 457 if (index_state == NodeStates::State::NoState) {
460 // Mark the node as seen 458 // Mark the node as seen
461 UpdateState(State::InFound, static_cast<u32>(current_stack_index)); 459 UpdateState(NodeStates::State::InFound, current_stack_index);
462 } else if (index_state == State::InFound) { 460 } else if (index_state == NodeStates::State::InFound) {
463 // We've seen this node before, mark it as completed 461 // We've seen this node before, mark it as completed
464 UpdateState(State::InCompleted, static_cast<u32>(current_stack_index)); 462 UpdateState(NodeStates::State::InCompleted, current_stack_index);
465 // Update our index list 463 // Update our index list
466 PushTsortResult(current_stack_index); 464 PushTsortResult(current_stack_index);
467 // Pop the stack 465 // Pop the stack
468 index_stack.pop(); 466 index_stack.pop();
469 continue; 467 continue;
470 } else if (index_state == State::InCompleted) { 468 } else if (index_state == NodeStates::State::InCompleted) {
471 // If our node is already sorted, clear it 469 // If our node is already sorted, clear it
472 index_stack.pop(); 470 index_stack.pop();
473 continue; 471 continue;
@@ -481,11 +479,11 @@ bool NodeStates::DepthFirstSearch(EdgeMatrix& edge_matrix) {
481 } 479 }
482 480
483 // Check if our node exists 481 // Check if our node exists
484 const auto node_state = GetState(static_cast<u32>(j)); 482 const auto node_state = GetState(j);
485 if (node_state == State::NoState) { 483 if (node_state == NodeStates::State::NoState) {
486 // Add more work 484 // Add more work
487 index_stack.push(j); 485 index_stack.push(j);
488 } else if (node_state == State::InFound) { 486 } else if (node_state == NodeStates::State::InFound) {
489 UNREACHABLE_MSG("Node start marked as found"); 487 UNREACHABLE_MSG("Node start marked as found");
490 ResetState(); 488 ResetState();
491 return false; 489 return false;
@@ -509,17 +507,17 @@ void NodeStates::ResetState() {
509 } 507 }
510} 508}
511 509
512void NodeStates::UpdateState(State state, std::size_t i) { 510void NodeStates::UpdateState(NodeStates::State state, std::size_t i) {
513 switch (state) { 511 switch (state) {
514 case State::NoState: 512 case NodeStates::State::NoState:
515 was_node_found[i] = false; 513 was_node_found[i] = false;
516 was_node_completed[i] = false; 514 was_node_completed[i] = false;
517 break; 515 break;
518 case State::InFound: 516 case NodeStates::State::InFound:
519 was_node_found[i] = true; 517 was_node_found[i] = true;
520 was_node_completed[i] = false; 518 was_node_completed[i] = false;
521 break; 519 break;
522 case State::InCompleted: 520 case NodeStates::State::InCompleted:
523 was_node_found[i] = false; 521 was_node_found[i] = false;
524 was_node_completed[i] = true; 522 was_node_completed[i] = true;
525 break; 523 break;
@@ -530,13 +528,13 @@ NodeStates::State NodeStates::GetState(std::size_t i) {
530 ASSERT(i < node_count); 528 ASSERT(i < node_count);
531 if (was_node_found[i]) { 529 if (was_node_found[i]) {
532 // If our node exists in our found list 530 // If our node exists in our found list
533 return State::InFound; 531 return NodeStates::State::InFound;
534 } else if (was_node_completed[i]) { 532 } else if (was_node_completed[i]) {
535 // If node is in the completed list 533 // If node is in the completed list
536 return State::InCompleted; 534 return NodeStates::State::InCompleted;
537 } else { 535 } else {
538 // If in neither 536 // If in neither
539 return State::NoState; 537 return NodeStates::State::NoState;
540 } 538 }
541} 539}
542 540
@@ -603,16 +601,16 @@ std::size_t EdgeMatrix::GetNodeCount() const {
603 601
604void EdgeMatrix::SetState(s32 a, s32 b, bool state) { 602void EdgeMatrix::SetState(s32 a, s32 b, bool state) {
605 ASSERT(InRange(a, b)); 603 ASSERT(InRange(a, b));
606 edge_matrix.at(static_cast<u32>(a) * node_count + static_cast<u32>(b)) = state; 604 edge_matrix.at(a * node_count + b) = state;
607} 605}
608 606
609bool EdgeMatrix::GetState(s32 a, s32 b) { 607bool EdgeMatrix::GetState(s32 a, s32 b) {
610 ASSERT(InRange(a, b)); 608 ASSERT(InRange(a, b));
611 return edge_matrix.at(static_cast<u32>(a) * node_count + static_cast<u32>(b)); 609 return edge_matrix.at(a * node_count + b);
612} 610}
613 611
614bool EdgeMatrix::InRange(s32 a, s32 b) const { 612bool EdgeMatrix::InRange(s32 a, s32 b) const {
615 const std::size_t pos = static_cast<u32>(a) * node_count + static_cast<u32>(b); 613 const std::size_t pos = a * node_count + b;
616 return pos < (node_count * node_count); 614 return pos < (node_count * node_count);
617} 615}
618 616