summaryrefslogtreecommitdiff
path: root/src/audio_core/hle/pipe.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/audio_core/hle/pipe.cpp')
-rw-r--r--src/audio_core/hle/pipe.cpp177
1 files changed, 0 insertions, 177 deletions
diff --git a/src/audio_core/hle/pipe.cpp b/src/audio_core/hle/pipe.cpp
deleted file mode 100644
index 24074a514..000000000
--- a/src/audio_core/hle/pipe.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <array>
6#include <vector>
7#include "audio_core/hle/dsp.h"
8#include "audio_core/hle/pipe.h"
9#include "common/assert.h"
10#include "common/common_types.h"
11#include "common/logging/log.h"
12#include "core/hle/service/dsp_dsp.h"
13
14namespace DSP {
15namespace HLE {
16
17static DspState dsp_state = DspState::Off;
18
19static std::array<std::vector<u8>, NUM_DSP_PIPE> pipe_data;
20
21void ResetPipes() {
22 for (auto& data : pipe_data) {
23 data.clear();
24 }
25 dsp_state = DspState::Off;
26}
27
28std::vector<u8> PipeRead(DspPipe pipe_number, u32 length) {
29 const size_t pipe_index = static_cast<size_t>(pipe_number);
30
31 if (pipe_index >= NUM_DSP_PIPE) {
32 LOG_ERROR(Audio_DSP, "pipe_number = %zu invalid", pipe_index);
33 return {};
34 }
35
36 if (length > UINT16_MAX) { // Can only read at most UINT16_MAX from the pipe
37 LOG_ERROR(Audio_DSP, "length of %u greater than max of %u", length, UINT16_MAX);
38 return {};
39 }
40
41 std::vector<u8>& data = pipe_data[pipe_index];
42
43 if (length > data.size()) {
44 LOG_WARNING(
45 Audio_DSP,
46 "pipe_number = %zu is out of data, application requested read of %u but %zu remain",
47 pipe_index, length, data.size());
48 length = static_cast<u32>(data.size());
49 }
50
51 if (length == 0)
52 return {};
53
54 std::vector<u8> ret(data.begin(), data.begin() + length);
55 data.erase(data.begin(), data.begin() + length);
56 return ret;
57}
58
59size_t GetPipeReadableSize(DspPipe pipe_number) {
60 const size_t pipe_index = static_cast<size_t>(pipe_number);
61
62 if (pipe_index >= NUM_DSP_PIPE) {
63 LOG_ERROR(Audio_DSP, "pipe_number = %zu invalid", pipe_index);
64 return 0;
65 }
66
67 return pipe_data[pipe_index].size();
68}
69
70static void WriteU16(DspPipe pipe_number, u16 value) {
71 const size_t pipe_index = static_cast<size_t>(pipe_number);
72
73 std::vector<u8>& data = pipe_data.at(pipe_index);
74 // Little endian
75 data.emplace_back(value & 0xFF);
76 data.emplace_back(value >> 8);
77}
78
79static void AudioPipeWriteStructAddresses() {
80 // These struct addresses are DSP dram addresses.
81 // See also: DSP_DSP::ConvertProcessAddressFromDspDram
82 static const std::array<u16, 15> struct_addresses = {
83 0x8000 + offsetof(SharedMemory, frame_counter) / 2,
84 0x8000 + offsetof(SharedMemory, source_configurations) / 2,
85 0x8000 + offsetof(SharedMemory, source_statuses) / 2,
86 0x8000 + offsetof(SharedMemory, adpcm_coefficients) / 2,
87 0x8000 + offsetof(SharedMemory, dsp_configuration) / 2,
88 0x8000 + offsetof(SharedMemory, dsp_status) / 2,
89 0x8000 + offsetof(SharedMemory, final_samples) / 2,
90 0x8000 + offsetof(SharedMemory, intermediate_mix_samples) / 2,
91 0x8000 + offsetof(SharedMemory, compressor) / 2,
92 0x8000 + offsetof(SharedMemory, dsp_debug) / 2,
93 0x8000 + offsetof(SharedMemory, unknown10) / 2,
94 0x8000 + offsetof(SharedMemory, unknown11) / 2,
95 0x8000 + offsetof(SharedMemory, unknown12) / 2,
96 0x8000 + offsetof(SharedMemory, unknown13) / 2,
97 0x8000 + offsetof(SharedMemory, unknown14) / 2,
98 };
99
100 // Begin with a u16 denoting the number of structs.
101 WriteU16(DspPipe::Audio, static_cast<u16>(struct_addresses.size()));
102 // Then write the struct addresses.
103 for (u16 addr : struct_addresses) {
104 WriteU16(DspPipe::Audio, addr);
105 }
106 // Signal that we have data on this pipe.
107 Service::DSP_DSP::SignalPipeInterrupt(DspPipe::Audio);
108}
109
110void PipeWrite(DspPipe pipe_number, const std::vector<u8>& buffer) {
111 switch (pipe_number) {
112 case DspPipe::Audio: {
113 if (buffer.size() != 4) {
114 LOG_ERROR(Audio_DSP, "DspPipe::Audio: Unexpected buffer length %zu was written",
115 buffer.size());
116 return;
117 }
118
119 enum class StateChange {
120 Initialize = 0,
121 Shutdown = 1,
122 Wakeup = 2,
123 Sleep = 3,
124 };
125
126 // The difference between Initialize and Wakeup is that Input state is maintained
127 // when sleeping but isn't when turning it off and on again. (TODO: Implement this.)
128 // Waking up from sleep garbles some of the structs in the memory region. (TODO:
129 // Implement this.) Applications store away the state of these structs before
130 // sleeping and reset it back after wakeup on behalf of the DSP.
131
132 switch (static_cast<StateChange>(buffer[0])) {
133 case StateChange::Initialize:
134 LOG_INFO(Audio_DSP, "Application has requested initialization of DSP hardware");
135 ResetPipes();
136 AudioPipeWriteStructAddresses();
137 dsp_state = DspState::On;
138 break;
139 case StateChange::Shutdown:
140 LOG_INFO(Audio_DSP, "Application has requested shutdown of DSP hardware");
141 dsp_state = DspState::Off;
142 break;
143 case StateChange::Wakeup:
144 LOG_INFO(Audio_DSP, "Application has requested wakeup of DSP hardware");
145 ResetPipes();
146 AudioPipeWriteStructAddresses();
147 dsp_state = DspState::On;
148 break;
149 case StateChange::Sleep:
150 LOG_INFO(Audio_DSP, "Application has requested sleep of DSP hardware");
151 UNIMPLEMENTED();
152 dsp_state = DspState::Sleeping;
153 break;
154 default:
155 LOG_ERROR(Audio_DSP,
156 "Application has requested unknown state transition of DSP hardware %hhu",
157 buffer[0]);
158 dsp_state = DspState::Off;
159 break;
160 }
161
162 return;
163 }
164 default:
165 LOG_CRITICAL(Audio_DSP, "pipe_number = %zu unimplemented",
166 static_cast<size_t>(pipe_number));
167 UNIMPLEMENTED();
168 return;
169 }
170}
171
172DspState GetDspState() {
173 return dsp_state;
174}
175
176} // namespace HLE
177} // namespace DSP