audio_renderer: Preliminary BehaviorInfo (#3736)
* audio_renderer: Preliminary BehaviorInfo * clang format * Fixed IsRevisionSupported * fixed IsValidRevision * Fixed logic error & spelling errors & crash * Addressed issuesmaster
parent
d3e0cefa60
commit
11c63ca969
@ -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
|
Loading…
Reference in New Issue