9a4beac95a
Preliminary work for upmixing & general cleanup. Fixes basic issues in games such as Shovel Knight and slightly improves the LEGO games. Upmixing stitll needs to be implemented. Audio levels in a few games will be fixed as we now use the downmix coefficients when possible instead of supplying our own
115 lines
3.5 KiB
C++
115 lines
3.5 KiB
C++
// 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 "audio_core/common.h"
|
|
#include "audio_core/splitter_context.h"
|
|
#include "common/common_funcs.h"
|
|
#include "common/common_types.h"
|
|
|
|
namespace AudioCore {
|
|
class BehaviorInfo;
|
|
class EffectContext;
|
|
|
|
class MixInfo {
|
|
public:
|
|
struct DirtyHeader {
|
|
u32_le magic{};
|
|
u32_le mixer_count{};
|
|
INSERT_PADDING_BYTES(0x18);
|
|
};
|
|
static_assert(sizeof(DirtyHeader) == 0x20, "MixInfo::DirtyHeader is an invalid size");
|
|
|
|
struct InParams {
|
|
float_le volume{};
|
|
s32_le sample_rate{};
|
|
s32_le buffer_count{};
|
|
bool in_use{};
|
|
INSERT_PADDING_BYTES(3);
|
|
s32_le mix_id{};
|
|
s32_le effect_count{};
|
|
u32_le node_id{};
|
|
INSERT_PADDING_WORDS(2);
|
|
std::array<std::array<float_le, AudioCommon::MAX_MIX_BUFFERS>, AudioCommon::MAX_MIX_BUFFERS>
|
|
mix_volume{};
|
|
s32_le dest_mix_id{};
|
|
s32_le splitter_id{};
|
|
INSERT_PADDING_WORDS(1);
|
|
};
|
|
static_assert(sizeof(MixInfo::InParams) == 0x930, "MixInfo::InParams is an invalid size");
|
|
};
|
|
|
|
class ServerMixInfo {
|
|
public:
|
|
struct InParams {
|
|
float volume{};
|
|
s32 sample_rate{};
|
|
s32 buffer_count{};
|
|
bool in_use{};
|
|
s32 mix_id{};
|
|
u32 node_id{};
|
|
std::array<std::array<float_le, AudioCommon::MAX_MIX_BUFFERS>, AudioCommon::MAX_MIX_BUFFERS>
|
|
mix_volume{};
|
|
s32 dest_mix_id{};
|
|
s32 splitter_id{};
|
|
s32 buffer_offset{};
|
|
s32 final_mix_distance{};
|
|
};
|
|
ServerMixInfo();
|
|
~ServerMixInfo();
|
|
|
|
[[nodiscard]] const ServerMixInfo::InParams& GetInParams() const;
|
|
[[nodiscard]] ServerMixInfo::InParams& GetInParams();
|
|
|
|
bool Update(EdgeMatrix& edge_matrix, const MixInfo::InParams& mix_in,
|
|
BehaviorInfo& behavior_info, SplitterContext& splitter_context,
|
|
EffectContext& effect_context);
|
|
[[nodiscard]] bool HasAnyConnection() const;
|
|
void Cleanup();
|
|
void SetEffectCount(std::size_t count);
|
|
void ResetEffectProcessingOrder();
|
|
[[nodiscard]] s32 GetEffectOrder(std::size_t i) const;
|
|
|
|
private:
|
|
std::vector<s32> effect_processing_order;
|
|
InParams in_params{};
|
|
bool UpdateConnection(EdgeMatrix& edge_matrix, const MixInfo::InParams& mix_in,
|
|
SplitterContext& splitter_context);
|
|
};
|
|
|
|
class MixContext {
|
|
public:
|
|
MixContext();
|
|
~MixContext();
|
|
|
|
void Initialize(const BehaviorInfo& behavior_info, std::size_t mix_count,
|
|
std::size_t effect_count);
|
|
void SortInfo();
|
|
bool TsortInfo(SplitterContext& splitter_context);
|
|
|
|
[[nodiscard]] std::size_t GetCount() const;
|
|
[[nodiscard]] ServerMixInfo& GetInfo(std::size_t i);
|
|
[[nodiscard]] const ServerMixInfo& GetInfo(std::size_t i) const;
|
|
[[nodiscard]] ServerMixInfo& GetSortedInfo(std::size_t i);
|
|
[[nodiscard]] const ServerMixInfo& GetSortedInfo(std::size_t i) const;
|
|
[[nodiscard]] ServerMixInfo& GetFinalMixInfo();
|
|
[[nodiscard]] const ServerMixInfo& GetFinalMixInfo() const;
|
|
[[nodiscard]] EdgeMatrix& GetEdgeMatrix();
|
|
[[nodiscard]] const EdgeMatrix& GetEdgeMatrix() const;
|
|
|
|
private:
|
|
void CalcMixBufferOffset();
|
|
void UpdateDistancesFromFinalMix();
|
|
|
|
NodeStates node_states{};
|
|
EdgeMatrix edge_matrix{};
|
|
std::size_t info_count{};
|
|
std::vector<ServerMixInfo> infos{};
|
|
std::vector<ServerMixInfo*> sorted_info{};
|
|
};
|
|
} // namespace AudioCore
|