Skip to content

Commit

Permalink
Merge pull request wheremyfoodat#503 from wheremyfoodat/moar-hle-dsp
Browse files Browse the repository at this point in the history
HLE DSP: Stub AAC
  • Loading branch information
wheremyfoodat authored May 1, 2024
2 parents 21492f8 + 6a424a7 commit 64dc0a0
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 7 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ set(HEADER_FILES include/emulator.hpp include/helpers.hpp include/termcolor.hpp
include/PICA/dynapica/shader_rec_emitter_arm64.hpp include/scheduler.hpp include/applets/error_applet.hpp
include/audio/dsp_core.hpp include/audio/null_core.hpp include/audio/teakra_core.hpp
include/audio/miniaudio_device.hpp include/ring_buffer.hpp include/bitfield.hpp include/audio/dsp_shared_mem.hpp
include/audio/hle_core.hpp include/capstone.hpp
include/audio/hle_core.hpp include/capstone.hpp include/audio/aac.hpp
)

cmrc_add_resource_library(
Expand Down
71 changes: 71 additions & 0 deletions include/audio/aac.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#pragma once
#include <array>
#include <type_traits>

#include "helpers.hpp"
#include "swap.hpp"

namespace Audio::AAC {
namespace ResultCode {
enum : u32 {
Success = 0,
};
}

// Enum values and struct definitions based off Citra
namespace Command {
enum : u16 {
Init = 0, // Initialize encoder/decoder
EncodeDecode = 1, // Encode/Decode AAC
Shutdown = 2, // Shutdown encoder/decoder
LoadState = 3,
SaveState = 4,
};
}

namespace SampleRate {
enum : u32 {
Rate48000 = 0,
Rate44100 = 1,
Rate32000 = 2,
Rate24000 = 3,
Rate22050 = 4,
Rate16000 = 5,
Rate12000 = 6,
Rate11025 = 7,
Rate8000 = 8,
};
}

namespace Mode {
enum : u16 {
None = 0,
Decode = 1,
Encode = 2,
};
}

struct DecodeResponse {
u32_le sampleRate;
u32_le channelCount;
u32_le size;
u32_le unknown1;
u32_le unknown2;
u32_le sampleCount;
};

struct Message {
u16_le mode = Mode::None; // Encode or decode AAC?
u16_le command = Command::Init;
u32_le resultCode = ResultCode::Success;

// Info on the AAC request
union {
std::array<u8, 24> commandData{};
DecodeResponse decodeResponse;
};
};

static_assert(sizeof(Message) == 32);
static_assert(std::is_trivially_copyable<Message>());
} // namespace Audio::AAC
4 changes: 2 additions & 2 deletions include/audio/dsp_shared_mem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,12 +294,12 @@ namespace Audio::HLE {

struct SourceStatus {
struct Status {
u8 isEnabled; ///< Is this channel enabled? (Doesn't have to be playing anything.)
u8 enabled; ///< Is this channel enabled? (Doesn't have to be playing anything.)
u8 currentBufferIDDirty; ///< Non-zero when current_buffer_id changes
u16_le syncCount; ///< Is set by the DSP to the value of SourceConfiguration::sync_count
u32_dsp samplePosition; ///< Number of samples into the current buffer
u16_le currentBufferID; ///< Updated when a buffer finishes playing
u16_le lastBufferID; ///< Updated when all buffers in the queue finish playing
u16_le previousBufferID; ///< Updated when all buffers in the queue finish playing
};

Status status[sourceCount];
Expand Down
2 changes: 2 additions & 0 deletions include/audio/hle_core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <queue>
#include <vector>

#include "audio/aac.hpp"
#include "audio/dsp_core.hpp"
#include "audio/dsp_shared_mem.hpp"
#include "memory.hpp"
Expand Down Expand Up @@ -166,6 +167,7 @@ namespace Audio {
}
}

void handleAACRequest(const AAC::Message& request);
void updateSourceConfig(Source& source, HLE::SourceConfiguration::Configuration& config, s16_le* adpcmCoefficients);
void generateFrame(StereoFrame<s16>& frame);
void generateFrame(DSPSource& source);
Expand Down
56 changes: 52 additions & 4 deletions src/core/audio/hle_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,26 @@ namespace Audio {
break;
}

case DSPPipeType::Binary:
Helpers::warn("Unimplemented write to binary pipe! Size: %d\n", size);
case DSPPipeType::Binary: {
log("Unimplemented write to binary pipe! Size: %d\n", size);

AAC::Message request;
if (size == sizeof(request)) {
std::array<u8, sizeof(request)> raw;
for (uint i = 0; i < size; i++) {
raw[i] = mem.read32(buffer + i);
}

std::memcpy(&request, raw.data(), sizeof(request));
handleAACRequest(request);
} else {
Helpers::warn("Invalid size for AAC request");
}

// This pipe and interrupt are normally used for requests like AAC decode
dspService.triggerPipeEvent(DSPPipeType::Binary);
break;
}

default: log("Audio::HLE_DSP: Wrote to unimplemented pipe %d\n", channel); break;
}
Expand Down Expand Up @@ -215,11 +229,11 @@ namespace Audio {

// Update write region of shared memory
auto& status = write.sourceStatuses.status[i];
status.isEnabled = source.enabled;
status.enabled = source.enabled;
status.syncCount = source.syncCount;
status.currentBufferIDDirty = source.isBufferIDDirty ? 1 : 0;
status.currentBufferID = source.currentBufferID;
status.lastBufferID = source.previousBufferID;
status.previousBufferID = source.previousBufferID;
// TODO: Properly update sample position
status.samplePosition = source.samplePosition;

Expand Down Expand Up @@ -488,6 +502,40 @@ namespace Audio {
return decodedSamples;
}

void HLE_DSP::handleAACRequest(const AAC::Message& request) {
AAC::Message response;

switch (request.command) {
case AAC::Command::EncodeDecode:
// Dummy response to stop games from hanging
// TODO: Fix this when implementing AAC
response.resultCode = AAC::ResultCode::Success;
response.decodeResponse.channelCount = 2;
response.decodeResponse.sampleCount = 1024;
response.decodeResponse.size = 0;
response.decodeResponse.sampleRate = AAC::SampleRate::Rate48000;

response.command = request.command;
response.mode = request.mode;
break;

case AAC::Command::Init:
case AAC::Command::Shutdown:
case AAC::Command::LoadState:
case AAC::Command::SaveState:
response = request;
response.resultCode = AAC::ResultCode::Success;
break;

default: Helpers::warn("Unknown AAC command type"); break;
}

// Copy response data to the binary pipe
auto& pipe = pipeData[DSPPipeType::Binary];
pipe.resize(sizeof(response));
std::memcpy(&pipe[0], &response, sizeof(response));
}

void DSPSource::reset() {
enabled = false;
isBufferIDDirty = false;
Expand Down

0 comments on commit 64dc0a0

Please sign in to comment.