From f3547a832f01dc217e4ed7f525dda8e1849012c0 Mon Sep 17 00:00:00 2001 From: gibbed Date: Fri, 19 Jun 2015 09:54:10 -0500 Subject: [PATCH] Removed XMAContextData::kSize constant, moved kXmaContextCount, changes to use newer ringbuffer, cleaned up XMAInitializeContext a bit (with fixes for loop_data handling). --- src/xenia/apu/audio_system.cc | 20 +++------ src/xenia/apu/audio_system.h | 9 ++-- src/xenia/kernel/xboxkrnl_audio_xma.cc | 62 ++++++++++++++++++-------- 3 files changed, 56 insertions(+), 35 deletions(-) diff --git a/src/xenia/apu/audio_system.cc b/src/xenia/apu/audio_system.cc index 23fc8f48d..d4580991e 100644 --- a/src/xenia/apu/audio_system.cc +++ b/src/xenia/apu/audio_system.cc @@ -56,11 +56,6 @@ namespace apu { using namespace xe::cpu; -// Size of a hardware XMA context. -const uint32_t kXmaContextSize = 64; -// Total number of XMA contexts available. -const uint32_t kXmaContextCount = 320; - AudioSystem::AudioSystem(Emulator* emulator) : emulator_(emulator), memory_(emulator->memory()), @@ -99,10 +94,10 @@ X_STATUS AudioSystem::Setup() { // Setup XMA contexts ptr. registers_.xma_context_array_ptr = memory()->SystemHeapAlloc( - kXmaContextSize * kXmaContextCount, 256, kSystemHeapPhysical); + sizeof(XMAContextData) * kXmaContextCount, 256, kSystemHeapPhysical); // Add all contexts to the free list. for (int i = kXmaContextCount - 1; i >= 0; --i) { - uint32_t ptr = registers_.xma_context_array_ptr + i * kXmaContextSize; + uint32_t ptr = registers_.xma_context_array_ptr + i * sizeof(XMAContextData); XMAContext& context = xma_context_array_[i]; @@ -268,7 +263,7 @@ void AudioSystem::ReleaseXmaContext(uint32_t guest_ptr) { context.in_use = false; auto context_ptr = memory()->TranslateVirtual(guest_ptr); - std::memset(context_ptr, 0, kXmaContextSize); // Zero it. + std::memset(context_ptr, 0, sizeof(XMAContextData)); // Zero it. context.decoder->DiscardPacket(); context.lock.unlock(); @@ -380,9 +375,8 @@ void AudioSystem::ProcessXmaContext(XMAContext& context, XMAContextData& data) { uint32_t output_write_offset_bytes = data.output_buffer_write_offset * 256; uint32_t output_read_offset_bytes = data.output_buffer_read_offset * 256; - RingBuffer output_buffer(out, output_size_bytes, output_write_offset_bytes); - size_t output_remaining_bytes - = output_buffer.DistanceToOffset(output_read_offset_bytes); + RingBuffer output_buffer(out, output_size_bytes, output_read_offset_bytes, output_write_offset_bytes); + size_t output_remaining_bytes = output_buffer.write_size(); if (!output_remaining_bytes) { // Can't write any more data. Break. @@ -618,8 +612,8 @@ void AudioSystem::WriteRegister(uint32_t addr, uint64_t value) { XMAContext& context = xma_context_array_[context_id]; XELOGAPU("AudioSystem: reset context %d", context_id); - uint32_t guest_ptr = - registers_.xma_context_array_ptr + context_id * kXmaContextSize; + uint32_t guest_ptr = registers_.xma_context_array_ptr + + context_id * sizeof(XMAContextData); context.lock.lock(); auto context_ptr = memory()->TranslateVirtual(context.guest_ptr); XMAContextData data(context_ptr); diff --git a/src/xenia/apu/audio_system.h b/src/xenia/apu/audio_system.h index b2d3b01f4..7373b4c66 100644 --- a/src/xenia/apu/audio_system.h +++ b/src/xenia/apu/audio_system.h @@ -38,7 +38,6 @@ class AudioDecoder; // http://pastebin.com/9amqJ2kQ struct XMAContextData { - static const uint32_t kSize = 64; static const uint32_t kBytesPerPacket = 2048; static const uint32_t kSamplesPerFrame = 512; static const uint32_t kSamplesPerSubframe = 128; @@ -100,6 +99,9 @@ struct XMAContextData { uint32_t output_buffer_read_offset : 5; uint32_t unk_dword_9 : 27; // StopWhenDone/InterruptWhenDone(?) + // DWORD 10-15 + uint32_t unk_dwords_10_15[6]; // reserved? + XMAContextData(const void* ptr) { xe::copy_and_swap_32_aligned(reinterpret_cast(this), reinterpret_cast(ptr), @@ -112,7 +114,7 @@ struct XMAContextData { sizeof(XMAContextData) / 4); } }; -static_assert(sizeof(XMAContextData) == 4 * 10, "Must be packed"); +static_assert_size(XMAContextData, 64); class AudioSystem { protected: @@ -211,7 +213,8 @@ class AudioSystem { AudioDecoder* decoder; }; - XMAContext xma_context_array_[320]; + static const uint32_t kXmaContextCount = 320; // // Total number of XMA contexts available. + XMAContext xma_context_array_[kXmaContextCount]; std::vector xma_context_free_list_; std::vector xma_context_used_list_; // XMA contexts in use diff --git a/src/xenia/kernel/xboxkrnl_audio_xma.cc b/src/xenia/kernel/xboxkrnl_audio_xma.cc index 9b0d3a58c..0d69f89f4 100644 --- a/src/xenia/kernel/xboxkrnl_audio_xma.cc +++ b/src/xenia/kernel/xboxkrnl_audio_xma.cc @@ -88,12 +88,36 @@ void StoreXmaContextIndexedRegister(KernelState* kernel_state, uint32_t base_reg, uint32_t context_ptr) { auto audio_system = kernel_state->emulator()->audio_system(); uint32_t hw_index = (context_ptr - audio_system->xma_context_array_ptr()) / - XMAContextData::kSize; + sizeof(XMAContextData); uint32_t reg_num = base_reg + (hw_index >> 5) * 4; uint32_t reg_value = 1 << (hw_index & 0x1F); audio_system->WriteRegister(reg_num, xe::byte_swap(reg_value)); } +struct X_XMA_CONTEXT_INIT_LOOP_DATA { + xe::be loop_start; + xe::be loop_end; + xe::be loop_count; + xe::be loop_subframe_end; + xe::be loop_subframe_skip; +}; + +struct X_XMA_CONTEXT_INIT { + xe::be input_buffer_0_ptr; + xe::be input_buffer_0_packet_count; + xe::be input_buffer_1_ptr; + xe::be input_buffer_1_packet_count; + xe::be input_buffer_read_offset; + xe::be output_buffer_ptr; + xe::be output_buffer_block_count; + xe::be work_buffer; + xe::be subframe_decode_count; + xe::be channel_count; + xe::be sample_rate; + X_XMA_CONTEXT_INIT_LOOP_DATA loop_data; +}; +static_assert_size(X_XMA_CONTEXT_INIT, 56); + SHIM_CALL XMAInitializeContext_shim(PPCContext* ppc_context, KernelState* kernel_state) { uint32_t context_ptr = SHIM_GET_ARG_32(0); @@ -101,29 +125,29 @@ SHIM_CALL XMAInitializeContext_shim(PPCContext* ppc_context, XELOGD("XMAInitializeContext(%.8X, %.8X)", context_ptr, context_init_ptr); - std::memset(SHIM_MEM_ADDR(context_ptr), 0, XMAContextData::kSize); + std::memset(SHIM_MEM_ADDR(context_ptr), 0, sizeof(XMAContextData)); XMAContextData context(SHIM_MEM_ADDR(context_ptr)); + auto context_init = (X_XMA_CONTEXT_INIT*)SHIM_MEM_ADDR(context_init_ptr); - context.input_buffer_0_ptr = SHIM_MEM_32(context_init_ptr + 0 * 4); - context.input_buffer_0_packet_count = SHIM_MEM_32(context_init_ptr + 1 * 4); - context.input_buffer_1_ptr = SHIM_MEM_32(context_init_ptr + 2 * 4); - context.input_buffer_1_packet_count = SHIM_MEM_32(context_init_ptr + 3 * 4); - context.input_buffer_read_offset = SHIM_MEM_32(context_init_ptr + 4 * 4); - context.output_buffer_ptr = SHIM_MEM_32(context_init_ptr + 5 * 4); - context.output_buffer_block_count = SHIM_MEM_32(context_init_ptr + 6 * 4); + context.input_buffer_0_ptr = context_init->input_buffer_0_ptr; + context.input_buffer_0_packet_count = context_init->input_buffer_0_packet_count; + context.input_buffer_1_ptr = context_init->input_buffer_1_ptr; + context.input_buffer_1_packet_count = context_init->input_buffer_1_packet_count; + context.input_buffer_read_offset = context_init->input_buffer_read_offset; + context.output_buffer_ptr = context_init->output_buffer_ptr; + context.output_buffer_block_count = context_init->output_buffer_block_count; - // context.work_buffer = SHIM_MEM_32(context_init_ptr + 7 * 4); // ? - context.subframe_decode_count = SHIM_MEM_32(context_init_ptr + 8 * 4); - context.is_stereo = SHIM_MEM_32(context_init_ptr + 9 * 4) == 2; - context.sample_rate = SHIM_MEM_32(context_init_ptr + 10 * 4); + // context.work_buffer = context_init->work_buffer; // ? + context.subframe_decode_count = context_init->subframe_decode_count; + context.is_stereo = context_init->channel_count == 2; + context.sample_rate = context_init->sample_rate; - uint32_t loop_data_ptr = context_init_ptr + 11 * 4; - context.loop_start = SHIM_MEM_32(loop_data_ptr + 0); - context.loop_end = SHIM_MEM_32(loop_data_ptr + 4); - context.loop_count = SHIM_MEM_8(loop_data_ptr + 6); - context.loop_subframe_end = SHIM_MEM_8(loop_data_ptr + 6); - context.loop_subframe_skip = SHIM_MEM_8(loop_data_ptr + 7); + context.loop_start = context_init->loop_data.loop_start; + context.loop_end = context_init->loop_data.loop_end; + context.loop_count = context_init->loop_data.loop_count; + context.loop_subframe_end = context_init->loop_data.loop_subframe_end; + context.loop_subframe_skip = context_init->loop_data.loop_subframe_skip; context.Store(SHIM_MEM_ADDR(context_ptr));