diff options
Diffstat (limited to 'src/core/hle')
| -rw-r--r-- | src/core/hle/service/audio/audren_u.cpp | 83 | ||||
| -rw-r--r-- | src/core/hle/service/audio/audren_u.h | 37 | 
2 files changed, 76 insertions, 44 deletions
| diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index 44b7ef216..653ded8e9 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp @@ -17,7 +17,8 @@ constexpr u64 audio_ticks{static_cast<u64>(CoreTiming::BASE_CLOCK_RATE / 200)};  class IAudioRenderer final : public ServiceFramework<IAudioRenderer> {  public: -    IAudioRenderer() : ServiceFramework("IAudioRenderer") { +    IAudioRenderer(AudioRendererParameters audren_params) +        : ServiceFramework("IAudioRenderer"), worker_params(audren_params) {          static const FunctionInfo functions[] = {              {0, nullptr, "GetAudioRendererSampleRate"},              {1, nullptr, "GetAudioRendererSampleCount"}, @@ -60,16 +61,27 @@ private:          AudioRendererConfig config;          auto buf = ctx.ReadBuffer();          std::memcpy(&config, buf.data(), sizeof(AudioRendererConfig)); +        u32 memory_pool_count = worker_params.effect_count + (worker_params.voice_count * 4); -        AudioRendererResponse response_data{config}; +        std::vector<MemoryPoolInfo> mem_pool_info(memory_pool_count); +        std::memcpy(mem_pool_info.data(), +                    buf.data() + sizeof(AudioRendererConfig) + config.behavior_size, +                    memory_pool_count * sizeof(MemoryPoolInfo)); + +        AudioRendererResponse response_data{worker_params};          ASSERT(ctx.GetWriteBufferSize() == response_data.total_size);          std::vector<u8> output(response_data.total_size);          std::memcpy(output.data(), &response_data, sizeof(AudioRendererResponse)); -        std::vector<MemoryPoolEntry> memory_pool(config.memory_pools_size / 0x20); -        for (auto& entry : memory_pool) { -            entry.state = 5; +        std::vector<MemoryPoolEntry> memory_pool(memory_pool_count); +        for (unsigned i = 0; i < memory_pool.size(); i++) { +            if (mem_pool_info[i].pool_state == MemoryPoolStates::RequestAttach) +                memory_pool[i].state = MemoryPoolStates::Attached; +            else if (mem_pool_info[i].pool_state == MemoryPoolStates::RequestDetach) +                memory_pool[i].state = MemoryPoolStates::Detached; +            else +                memory_pool[i].state = mem_pool_info[i].pool_state;          }          std::memcpy(output.data() + sizeof(AudioRendererResponse), memory_pool.data(),                      response_data.memory_pools_size); @@ -108,14 +120,32 @@ private:          NGLOG_WARNING(Service_Audio, "(STUBBED) called");      } +    enum class MemoryPoolStates : u32 { // Should be LE +        Invalid = 0x0, +        Unknown = 0x1, +        RequestDetach = 0x2, +        Detached = 0x3, +        RequestAttach = 0x4, +        Attached = 0x5, +        Released = 0x6, +    }; +      struct MemoryPoolEntry { -        u32_le state; +        MemoryPoolStates state;          u32_le unknown_4;          u32_le unknown_8;          u32_le unknown_c;      };      static_assert(sizeof(MemoryPoolEntry) == 0x10, "MemoryPoolEntry has wrong size"); +    struct MemoryPoolInfo { +        u64_le pool_address; +        u64_le pool_size; +        MemoryPoolStates pool_state; +        INSERT_PADDING_WORDS(3); // Unknown +    }; +    static_assert(sizeof(MemoryPoolInfo) == 0x20, "MemoryPoolInfo has wrong size"); +      struct AudioRendererConfig {          u32 revision;          u32 behavior_size; @@ -132,13 +162,13 @@ private:      static_assert(sizeof(AudioRendererConfig) == 0x40, "AudioRendererConfig has wrong size");      struct AudioRendererResponse { -        AudioRendererResponse(const AudioRendererConfig& config) { +        AudioRendererResponse(const AudioRendererParameters& config) {              revision = config.revision;              error_info_size = 0xb0; -            memory_pools_size = (config.memory_pools_size / 0x20) * 0x10; -            voices_size = (config.voices_size / 0x170) * 0x10; -            effects_size = (config.effects_size / 0xC0) * 0x10; -            sinks_size = (config.sinks_size / 0x140) * 0x20; +            memory_pools_size = (config.effect_count + (config.voice_count * 4)) * 0x10; +            voices_size = config.voice_count * 0x10; +            effects_size = config.effect_count * 0x10; +            sinks_size = config.sink_count * 0x20;              performance_manager_size = 0x10;              total_size = sizeof(AudioRendererResponse) + error_info_size + memory_pools_size +                           voices_size + effects_size + sinks_size + performance_manager_size; @@ -162,6 +192,7 @@ private:      CoreTiming::EventType* audio_event;      Kernel::SharedPtr<Kernel::Event> system_event; +    AudioRendererParameters worker_params;  };  class IAudioDevice final : public ServiceFramework<IAudioDevice> { @@ -259,10 +290,12 @@ AudRenU::AudRenU() : ServiceFramework("audren:u") {  }  void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) { +    IPC::RequestParser rp{ctx}; +    auto params = rp.PopRaw<AudioRendererParameters>();      IPC::ResponseBuilder rb{ctx, 2, 0, 1};      rb.Push(RESULT_SUCCESS); -    rb.PushIpcInterface<Audio::IAudioRenderer>(); +    rb.PushIpcInterface<Audio::IAudioRenderer>(std::move(params));      NGLOG_DEBUG(Service_Audio, "called");  } @@ -271,19 +304,19 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {      IPC::RequestParser rp{ctx};      auto params = rp.PopRaw<AudioRendererParameters>(); -    u64 buffer_sz = Common::AlignUp(4 * params.unknown8, 0x40); -    buffer_sz += params.unknownC * 1024; -    buffer_sz += 0x940 * (params.unknownC + 1); +    u64 buffer_sz = Common::AlignUp(4 * params.unknown_8, 0x40); +    buffer_sz += params.unknown_c * 1024; +    buffer_sz += 0x940 * (params.unknown_c + 1);      buffer_sz += 0x3F0 * params.voice_count; -    buffer_sz += Common::AlignUp(8 * (params.unknownC + 1), 0x10); +    buffer_sz += Common::AlignUp(8 * (params.unknown_c + 1), 0x10);      buffer_sz += Common::AlignUp(8 * params.voice_count, 0x10);      buffer_sz += -        Common::AlignUp((0x3C0 * (params.sink_count + params.unknownC) + 4 * params.sample_count) * -                            (params.unknown8 + 6), +        Common::AlignUp((0x3C0 * (params.sink_count + params.unknown_c) + 4 * params.sample_count) * +                            (params.unknown_8 + 6),                          0x40); -    if (IsFeatureSupported(AudioFeatures::Splitter, params.magic)) { -        u32 count = params.unknownC + 1; +    if (IsFeatureSupported(AudioFeatures::Splitter, params.revision)) { +        u32 count = params.unknown_c + 1;          u64 node_count = Common::AlignUp(count, 0x40);          u64 node_state_buffer_sz =              4 * (node_count * node_count) + 0xC * node_count + 2 * (node_count / 8); @@ -298,20 +331,20 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {      }      buffer_sz += 0x20 * (params.effect_count + 4 * params.voice_count) + 0x50; -    if (IsFeatureSupported(AudioFeatures::Splitter, params.magic)) { -        buffer_sz += 0xE0 * params.unknown2c; +    if (IsFeatureSupported(AudioFeatures::Splitter, params.revision)) { +        buffer_sz += 0xE0 * params.unknown_2c;          buffer_sz += 0x20 * params.splitter_count; -        buffer_sz += Common::AlignUp(4 * params.unknown2c, 0x10); +        buffer_sz += Common::AlignUp(4 * params.unknown_2c, 0x10);      }      buffer_sz = Common::AlignUp(buffer_sz, 0x40) + 0x170 * params.sink_count;      u64 output_sz = buffer_sz + 0x280 * params.sink_count + 0x4B0 * params.effect_count +                      ((params.voice_count * 256) | 0x40); -    if (params.unknown1c >= 1) { +    if (params.unknown_1c >= 1) {          output_sz = Common::AlignUp(((16 * params.sink_count + 16 * params.effect_count +                                        16 * params.voice_count + 16) +                                       0x658) * -                                            (params.unknown1c + 1) + +                                            (params.unknown_1c + 1) +                                          0xc0,                                      0x40) +                      output_sz; diff --git a/src/core/hle/service/audio/audren_u.h b/src/core/hle/service/audio/audren_u.h index 7dbd9b74d..e8baf99ee 100644 --- a/src/core/hle/service/audio/audren_u.h +++ b/src/core/hle/service/audio/audren_u.h @@ -12,6 +12,24 @@ class HLERequestContext;  namespace Service::Audio { +struct AudioRendererParameters { +    u32_le sample_rate; +    u32_le sample_count; +    u32_le unknown_8; +    u32_le unknown_c; +    u32_le voice_count; +    u32_le sink_count; +    u32_le effect_count; +    u32_le unknown_1c; +    u8 unknown_20; +    INSERT_PADDING_BYTES(3); +    u32_le splitter_count; +    u32_le unknown_2c; +    INSERT_PADDING_WORDS(1); +    u32_le revision; +}; +static_assert(sizeof(AudioRendererParameters) == 52, "AudioRendererParameters is an invalid size"); +  class AudRenU final : public ServiceFramework<AudRenU> {  public:      explicit AudRenU(); @@ -22,25 +40,6 @@ private:      void GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx);      void GetAudioDevice(Kernel::HLERequestContext& ctx); -    struct AudioRendererParameters { -        u32_le sample_rate; -        u32_le sample_count; -        u32_le unknown8; -        u32_le unknownC; -        u32_le voice_count; -        u32_le sink_count; -        u32_le effect_count; -        u32_le unknown1c; -        u8 unknown20; -        u8 padding1[3]; -        u32_le splitter_count; -        u32_le unknown2c; -        u8 padding2[4]; -        u32_le magic; -    }; -    static_assert(sizeof(AudioRendererParameters) == 52, -                  "AudioRendererParameters is an invalid size"); -      enum class AudioFeatures : u32 {          Splitter,      }; | 
