summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/audio_core/hle/source.cpp44
-rw-r--r--src/audio_core/hle/source.h2
2 files changed, 35 insertions, 11 deletions
diff --git a/src/audio_core/hle/source.cpp b/src/audio_core/hle/source.cpp
index 2bbf7146e..92484c526 100644
--- a/src/audio_core/hle/source.cpp
+++ b/src/audio_core/hle/source.cpp
@@ -158,6 +158,14 @@ void Source::ParseConfig(SourceConfiguration::Configuration& config,
158 static_cast<size_t>(state.mono_or_stereo)); 158 static_cast<size_t>(state.mono_or_stereo));
159 } 159 }
160 160
161 u32_dsp play_position = {};
162 if (config.play_position_dirty && config.play_position != 0) {
163 config.play_position_dirty.Assign(0);
164 play_position = config.play_position;
165 // play_position applies only to the embedded buffer, and defaults to 0 w/o a dirty bit
166 // This will be the starting sample for the first time the buffer is played.
167 }
168
161 if (config.embedded_buffer_dirty) { 169 if (config.embedded_buffer_dirty) {
162 config.embedded_buffer_dirty.Assign(0); 170 config.embedded_buffer_dirty.Assign(0);
163 state.input_queue.emplace(Buffer{ 171 state.input_queue.emplace(Buffer{
@@ -171,9 +179,18 @@ void Source::ParseConfig(SourceConfiguration::Configuration& config,
171 state.mono_or_stereo, 179 state.mono_or_stereo,
172 state.format, 180 state.format,
173 false, 181 false,
182 play_position,
183 false,
174 }); 184 });
175 LOG_TRACE(Audio_DSP, "enqueuing embedded addr=0x%08x len=%u id=%hu", 185 LOG_TRACE(Audio_DSP, "enqueuing embedded addr=0x%08x len=%u id=%hu start=%u",
176 config.physical_address, config.length, config.buffer_id); 186 config.physical_address, config.length, config.buffer_id,
187 static_cast<u32>(config.play_position));
188 }
189
190 if (config.loop_related_dirty && config.loop_related != 0) {
191 config.loop_related_dirty.Assign(0);
192 LOG_WARNING(Audio_DSP, "Unhandled complex loop with loop_related=0x%08x",
193 static_cast<u32>(config.loop_related));
177 } 194 }
178 195
179 if (config.buffer_queue_dirty) { 196 if (config.buffer_queue_dirty) {
@@ -192,6 +209,8 @@ void Source::ParseConfig(SourceConfiguration::Configuration& config,
192 state.mono_or_stereo, 209 state.mono_or_stereo,
193 state.format, 210 state.format,
194 true, 211 true,
212 {}, // 0 in u32_dsp
213 false,
195 }); 214 });
196 LOG_TRACE(Audio_DSP, "enqueuing queued %zu addr=0x%08x len=%u id=%hu", i, 215 LOG_TRACE(Audio_DSP, "enqueuing queued %zu addr=0x%08x len=%u id=%hu", i,
197 b.physical_address, b.length, b.buffer_id); 216 b.physical_address, b.length, b.buffer_id);
@@ -247,18 +266,18 @@ bool Source::DequeueBuffer() {
247 if (state.input_queue.empty()) 266 if (state.input_queue.empty())
248 return false; 267 return false;
249 268
250 const Buffer buf = state.input_queue.top(); 269 Buffer buf = state.input_queue.top();
251 state.input_queue.pop(); 270
271 // if we're in a loop, the current sound keeps playing afterwards, so leave the queue alone
272 if (!buf.is_looping) {
273 state.input_queue.pop();
274 }
252 275
253 if (buf.adpcm_dirty) { 276 if (buf.adpcm_dirty) {
254 state.adpcm_state.yn1 = buf.adpcm_yn[0]; 277 state.adpcm_state.yn1 = buf.adpcm_yn[0];
255 state.adpcm_state.yn2 = buf.adpcm_yn[1]; 278 state.adpcm_state.yn2 = buf.adpcm_yn[1];
256 } 279 }
257 280
258 if (buf.is_looping) {
259 LOG_ERROR(Audio_DSP, "Looped buffers are unimplemented at the moment");
260 }
261
262 const u8* const memory = Memory::GetPhysicalPointer(buf.physical_address); 281 const u8* const memory = Memory::GetPhysicalPointer(buf.physical_address);
263 if (memory) { 282 if (memory) {
264 const unsigned num_channels = buf.mono_or_stereo == MonoOrStereo::Stereo ? 2 : 1; 283 const unsigned num_channels = buf.mono_or_stereo == MonoOrStereo::Stereo ? 2 : 1;
@@ -305,10 +324,13 @@ bool Source::DequeueBuffer() {
305 break; 324 break;
306 } 325 }
307 326
308 state.current_sample_number = 0; 327 // the first playthrough starts at play_position, loops start at the beginning of the buffer
309 state.next_sample_number = 0; 328 state.current_sample_number = (!buf.has_played) ? buf.play_position : 0;
329 state.next_sample_number = state.current_sample_number;
310 state.current_buffer_id = buf.buffer_id; 330 state.current_buffer_id = buf.buffer_id;
311 state.buffer_update = buf.from_queue; 331 state.buffer_update = buf.from_queue && !buf.has_played;
332
333 buf.has_played = true;
312 334
313 LOG_TRACE(Audio_DSP, "source_id=%zu buffer_id=%hu from_queue=%s current_buffer.size()=%zu", 335 LOG_TRACE(Audio_DSP, "source_id=%zu buffer_id=%hu from_queue=%s current_buffer.size()=%zu",
314 source_id, buf.buffer_id, buf.from_queue ? "true" : "false", 336 source_id, buf.buffer_id, buf.from_queue ? "true" : "false",
diff --git a/src/audio_core/hle/source.h b/src/audio_core/hle/source.h
index 3d725f2a3..ccb7f064f 100644
--- a/src/audio_core/hle/source.h
+++ b/src/audio_core/hle/source.h
@@ -76,6 +76,8 @@ private:
76 Format format; 76 Format format;
77 77
78 bool from_queue; 78 bool from_queue;
79 u32_dsp play_position; // = 0;
80 bool has_played; // = false;
79 }; 81 };
80 82
81 struct BufferOrder { 83 struct BufferOrder {