Browse Source
audio_renderer: Preliminary BehaviorInfo (#3736)
audio_renderer: Preliminary BehaviorInfo (#3736)
* audio_renderer: Preliminary BehaviorInfo * clang format * Fixed IsRevisionSupported * fixed IsValidRevision * Fixed logic error & spelling errors & crash * Addressed issuespull/15/merge
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 249 additions and 13 deletions
-
3src/audio_core/CMakeLists.txt
-
32src/audio_core/audio_renderer.cpp
-
5src/audio_core/audio_renderer.h
-
100src/audio_core/behavior_info.cpp
-
66src/audio_core/behavior_info.h
-
47src/audio_core/common.h
-
9src/core/hle/service/audio/audren_u.cpp
@ -0,0 +1,100 @@ |
|||
// Copyright 2020 yuzu Emulator Project
|
|||
// Licensed under GPLv2 or any later version
|
|||
// Refer to the license.txt file included.
|
|||
|
|||
#include <cstring>
|
|||
#include "audio_core/behavior_info.h"
|
|||
#include "audio_core/common.h"
|
|||
#include "common/logging/log.h"
|
|||
|
|||
namespace AudioCore { |
|||
|
|||
BehaviorInfo::BehaviorInfo() : process_revision(CURRENT_PROCESS_REVISION) {} |
|||
BehaviorInfo::~BehaviorInfo() = default; |
|||
|
|||
bool BehaviorInfo::UpdateInput(const std::vector<u8>& buffer, std::size_t offset) { |
|||
if (!CanConsumeBuffer(buffer.size(), offset, sizeof(InParams))) { |
|||
LOG_ERROR(Audio, "Buffer is an invalid size!"); |
|||
return false; |
|||
} |
|||
InParams params{}; |
|||
std::memcpy(¶ms, buffer.data() + offset, sizeof(InParams)); |
|||
|
|||
if (!IsValidRevision(params.revision)) { |
|||
LOG_ERROR(Audio, "Invalid input revision, revision=0x{:08X}", params.revision); |
|||
return false; |
|||
} |
|||
|
|||
if (user_revision != params.revision) { |
|||
LOG_ERROR(Audio, |
|||
"User revision differs from input revision, expecting 0x{:08X} but got 0x{:08X}", |
|||
user_revision, params.revision); |
|||
return false; |
|||
} |
|||
|
|||
ClearError(); |
|||
UpdateFlags(params.flags); |
|||
|
|||
// TODO(ogniK): Check input params size when InfoUpdater is used
|
|||
|
|||
return true; |
|||
} |
|||
|
|||
bool BehaviorInfo::UpdateOutput(std::vector<u8>& buffer, std::size_t offset) { |
|||
if (!CanConsumeBuffer(buffer.size(), offset, sizeof(OutParams))) { |
|||
LOG_ERROR(Audio, "Buffer is an invalid size!"); |
|||
return false; |
|||
} |
|||
|
|||
OutParams params{}; |
|||
std::memcpy(params.errors.data(), errors.data(), sizeof(ErrorInfo) * errors.size()); |
|||
params.error_count = static_cast<u32_le>(error_count); |
|||
std::memcpy(buffer.data() + offset, ¶ms, sizeof(OutParams)); |
|||
return true; |
|||
} |
|||
|
|||
void BehaviorInfo::ClearError() { |
|||
error_count = 0; |
|||
} |
|||
|
|||
void BehaviorInfo::UpdateFlags(u64_le dest_flags) { |
|||
flags = dest_flags; |
|||
} |
|||
|
|||
void BehaviorInfo::SetUserRevision(u32_le revision) { |
|||
user_revision = revision; |
|||
} |
|||
|
|||
bool BehaviorInfo::IsAdpcmLoopContextBugFixed() const { |
|||
return IsRevisionSupported(2, user_revision); |
|||
} |
|||
|
|||
bool BehaviorInfo::IsSplitterSupported() const { |
|||
return IsRevisionSupported(2, user_revision); |
|||
} |
|||
|
|||
bool BehaviorInfo::IsLongSizePreDelaySupported() const { |
|||
return IsRevisionSupported(3, user_revision); |
|||
} |
|||
|
|||
bool BehaviorInfo::IsAudioRenererProcessingTimeLimit80PercentSupported() const { |
|||
return IsRevisionSupported(5, user_revision); |
|||
} |
|||
|
|||
bool BehaviorInfo::IsAudioRenererProcessingTimeLimit75PercentSupported() const { |
|||
return IsRevisionSupported(4, user_revision); |
|||
} |
|||
|
|||
bool BehaviorInfo::IsAudioRenererProcessingTimeLimit70PercentSupported() const { |
|||
return IsRevisionSupported(1, user_revision); |
|||
} |
|||
|
|||
bool BehaviorInfo::IsElapsedFrameCountSupported() const { |
|||
return IsRevisionSupported(5, user_revision); |
|||
} |
|||
|
|||
bool BehaviorInfo::IsMemoryPoolForceMappingEnabled() const { |
|||
return (flags & 1) != 0; |
|||
} |
|||
|
|||
} // namespace AudioCore
|
|||
@ -0,0 +1,66 @@ |
|||
// Copyright 2020 yuzu Emulator Project |
|||
// Licensed under GPLv2 or any later version |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
|
|||
#include <vector> |
|||
#include "common/common_funcs.h" |
|||
#include "common/common_types.h" |
|||
#include "common/swap.h" |
|||
|
|||
namespace AudioCore { |
|||
class BehaviorInfo { |
|||
public: |
|||
explicit BehaviorInfo(); |
|||
~BehaviorInfo(); |
|||
|
|||
bool UpdateInput(const std::vector<u8>& buffer, std::size_t offset); |
|||
bool UpdateOutput(std::vector<u8>& buffer, std::size_t offset); |
|||
|
|||
void ClearError(); |
|||
void UpdateFlags(u64_le dest_flags); |
|||
void SetUserRevision(u32_le revision); |
|||
|
|||
bool IsAdpcmLoopContextBugFixed() const; |
|||
bool IsSplitterSupported() const; |
|||
bool IsLongSizePreDelaySupported() const; |
|||
bool IsAudioRenererProcessingTimeLimit80PercentSupported() const; |
|||
bool IsAudioRenererProcessingTimeLimit75PercentSupported() const; |
|||
bool IsAudioRenererProcessingTimeLimit70PercentSupported() const; |
|||
bool IsElapsedFrameCountSupported() const; |
|||
bool IsMemoryPoolForceMappingEnabled() const; |
|||
|
|||
private: |
|||
u32_le process_revision{}; |
|||
u32_le user_revision{}; |
|||
u64_le flags{}; |
|||
|
|||
struct ErrorInfo { |
|||
u32_le result{}; |
|||
INSERT_PADDING_WORDS(1); |
|||
u64_le result_info{}; |
|||
}; |
|||
static_assert(sizeof(ErrorInfo) == 0x10, "ErrorInfo is an invalid size"); |
|||
|
|||
std::array<ErrorInfo, 10> errors{}; |
|||
std::size_t error_count{}; |
|||
|
|||
struct InParams { |
|||
u32_le revision{}; |
|||
u32_le padding{}; |
|||
u64_le flags{}; |
|||
}; |
|||
static_assert(sizeof(InParams) == 0x10, "InParams is an invalid size"); |
|||
|
|||
struct OutParams { |
|||
std::array<ErrorInfo, 10> errors{}; |
|||
u32_le error_count{}; |
|||
INSERT_PADDING_BYTES(12); |
|||
}; |
|||
static_assert(sizeof(OutParams) == 0xb0, "OutParams is an invalid size"); |
|||
}; |
|||
|
|||
} // namespace AudioCore |
|||
@ -0,0 +1,47 @@ |
|||
// Copyright 2020 yuzu Emulator Project |
|||
// Licensed under GPLv2 or any later version |
|||
// Refer to the license.txt file included. |
|||
|
|||
#pragma once |
|||
#include "common/common_funcs.h" |
|||
#include "common/common_types.h" |
|||
#include "common/swap.h" |
|||
#include "core/hle/result.h" |
|||
|
|||
namespace AudioCore { |
|||
namespace Audren { |
|||
constexpr ResultCode ERR_INVALID_PARAMETERS{ErrorModule::Audio, 41}; |
|||
} |
|||
|
|||
constexpr u32_le CURRENT_PROCESS_REVISION = Common::MakeMagic('R', 'E', 'V', '8'); |
|||
|
|||
static constexpr u32 VersionFromRevision(u32_le rev) { |
|||
// "REV7" -> 7 |
|||
return ((rev >> 24) & 0xff) - 0x30; |
|||
} |
|||
|
|||
static constexpr bool IsRevisionSupported(u32 required, u32_le user_revision) { |
|||
const auto base = VersionFromRevision(user_revision); |
|||
return required <= base; |
|||
} |
|||
|
|||
static constexpr bool IsValidRevision(u32_le revision) { |
|||
const auto base = VersionFromRevision(revision); |
|||
constexpr auto max_rev = VersionFromRevision(CURRENT_PROCESS_REVISION); |
|||
return base <= max_rev; |
|||
} |
|||
|
|||
static constexpr bool CanConsumeBuffer(std::size_t size, std::size_t offset, std::size_t required) { |
|||
if (offset > size) { |
|||
return false; |
|||
} |
|||
if (size < required) { |
|||
return false; |
|||
} |
|||
if ((size - offset) < required) { |
|||
return false; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
} // namespace AudioCore |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue