summaryrefslogtreecommitdiffstats
path: root/src/audio_core/command_generator.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/audio_core/command_generator.cpp216
1 files changed, 133 insertions, 83 deletions
diff --git a/src/audio_core/command_generator.cpp b/src/audio_core/command_generator.cpp
index 437cc5ccd..b99d0fc91 100644
--- a/src/audio_core/command_generator.cpp
+++ b/src/audio_core/command_generator.cpp
@@ -31,7 +31,7 @@ constexpr std::array<f32, AudioCommon::I3DL2REVERB_TAPS> EARLY_GAIN{
0.72867f, 0.69794f, 0.5464f, 0.24563f, 0.45214f, 0.44042f};
template <std::size_t N>
-void ApplyMix(s32* output, const s32* input, s32 gain, s32 sample_count) {
+void ApplyMix(std::span<s32> output, std::span<const s32> input, s32 gain, s32 sample_count) {
for (std::size_t i = 0; i < static_cast<std::size_t>(sample_count); i += N) {
for (std::size_t j = 0; j < N; j++) {
output[i + j] +=
@@ -40,7 +40,8 @@ void ApplyMix(s32* output, const s32* input, s32 gain, s32 sample_count) {
}
}
-s32 ApplyMixRamp(s32* output, const s32* input, float gain, float delta, s32 sample_count) {
+s32 ApplyMixRamp(std::span<s32> output, std::span<const s32> input, float gain, float delta,
+ s32 sample_count) {
s32 x = 0;
for (s32 i = 0; i < sample_count; i++) {
x = static_cast<s32>(static_cast<float>(input[i]) * gain);
@@ -50,20 +51,22 @@ s32 ApplyMixRamp(s32* output, const s32* input, float gain, float delta, s32 sam
return x;
}
-void ApplyGain(s32* output, const s32* input, s32 gain, s32 delta, s32 sample_count) {
+void ApplyGain(std::span<s32> output, std::span<const s32> input, s32 gain, s32 delta,
+ s32 sample_count) {
for (s32 i = 0; i < sample_count; i++) {
output[i] = static_cast<s32>((static_cast<s64>(input[i]) * gain + 0x4000) >> 15);
gain += delta;
}
}
-void ApplyGainWithoutDelta(s32* output, const s32* input, s32 gain, s32 sample_count) {
+void ApplyGainWithoutDelta(std::span<s32> output, std::span<const s32> input, s32 gain,
+ s32 sample_count) {
for (s32 i = 0; i < sample_count; i++) {
output[i] = static_cast<s32>((static_cast<s64>(input[i]) * gain + 0x4000) >> 15);
}
}
-s32 ApplyMixDepop(s32* output, s32 first_sample, s32 delta, s32 sample_count) {
+s32 ApplyMixDepop(std::span<s32> output, s32 first_sample, s32 delta, s32 sample_count) {
const bool positive = first_sample > 0;
auto final_sample = std::abs(first_sample);
for (s32 i = 0; i < sample_count; i++) {
@@ -128,10 +131,10 @@ constexpr std::array<std::size_t, 20> REVERB_TAP_INDEX_6CH{4, 0, 0, 1, 1, 1, 1,
1, 1, 1, 0, 0, 0, 0, 3, 3, 3};
template <std::size_t CHANNEL_COUNT>
-void ApplyReverbGeneric(I3dl2ReverbState& state,
- const std::array<const s32*, AudioCommon::MAX_CHANNEL_COUNT>& input,
- const std::array<s32*, AudioCommon::MAX_CHANNEL_COUNT>& output,
- s32 sample_count) {
+void ApplyReverbGeneric(
+ I3dl2ReverbState& state,
+ const std::array<std::span<const s32>, AudioCommon::MAX_CHANNEL_COUNT>& input,
+ const std::array<std::span<s32>, AudioCommon::MAX_CHANNEL_COUNT>& output, s32 sample_count) {
auto GetTapLookup = []() {
if constexpr (CHANNEL_COUNT == 1) {
@@ -400,7 +403,10 @@ void CommandGenerator::GenerateDataSourceCommand(ServerVoiceInfo& voice_info, Vo
}
} else {
switch (in_params.sample_format) {
+ case SampleFormat::Pcm8:
case SampleFormat::Pcm16:
+ case SampleFormat::Pcm32:
+ case SampleFormat::PcmFloat:
DecodeFromWaveBuffers(voice_info, GetChannelMixBuffer(channel), dsp_state, channel,
worker_params.sample_rate, worker_params.sample_count,
in_params.node_id);
@@ -454,8 +460,8 @@ void CommandGenerator::GenerateBiquadFilterCommand([[maybe_unused]] s32 mix_buff
"input_mix_buffer={}, output_mix_buffer={}",
node_id, input_offset, output_offset);
}
- const auto* input = GetMixBuffer(input_offset);
- auto* output = GetMixBuffer(output_offset);
+ std::span<const s32> input = GetMixBuffer(input_offset);
+ std::span<s32> output = GetMixBuffer(output_offset);
// Biquad filter parameters
const auto [n0, n1, n2] = params.numerator;
@@ -548,8 +554,8 @@ void CommandGenerator::GenerateI3dl2ReverbEffectCommand(s32 mix_buffer_offset, E
return;
}
- std::array<const s32*, AudioCommon::MAX_CHANNEL_COUNT> input{};
- std::array<s32*, AudioCommon::MAX_CHANNEL_COUNT> output{};
+ std::array<std::span<const s32>, AudioCommon::MAX_CHANNEL_COUNT> input{};
+ std::array<std::span<s32>, AudioCommon::MAX_CHANNEL_COUNT> output{};
const auto status = params.status;
for (s32 i = 0; i < channel_count; i++) {
@@ -584,7 +590,8 @@ void CommandGenerator::GenerateI3dl2ReverbEffectCommand(s32 mix_buffer_offset, E
for (s32 i = 0; i < channel_count; i++) {
// Only copy if the buffer input and output do not match!
if ((mix_buffer_offset + params.input[i]) != (mix_buffer_offset + params.output[i])) {
- std::memcpy(output[i], input[i], worker_params.sample_count * sizeof(s32));
+ std::memcpy(output[i].data(), input[i].data(),
+ worker_params.sample_count * sizeof(s32));
}
}
}
@@ -600,8 +607,8 @@ void CommandGenerator::GenerateBiquadFilterEffectCommand(s32 mix_buffer_offset,
for (s32 i = 0; i < channel_count; i++) {
// TODO(ogniK): Actually implement biquad filter
if (params.input[i] != params.output[i]) {
- const auto* input = GetMixBuffer(mix_buffer_offset + params.input[i]);
- auto* output = GetMixBuffer(mix_buffer_offset + params.output[i]);
+ std::span<const s32> input = GetMixBuffer(mix_buffer_offset + params.input[i]);
+ std::span<s32> output = GetMixBuffer(mix_buffer_offset + params.output[i]);
ApplyMix<1>(output, input, 32768, worker_params.sample_count);
}
}
@@ -640,14 +647,15 @@ void CommandGenerator::GenerateAuxCommand(s32 mix_buffer_offset, EffectBase* inf
if (samples_read != static_cast<int>(worker_params.sample_count) &&
samples_read <= params.sample_count) {
- std::memset(GetMixBuffer(output_index), 0, params.sample_count - samples_read);
+ std::memset(GetMixBuffer(output_index).data(), 0,
+ params.sample_count - samples_read);
}
} else {
AuxInfoDSP empty{};
memory.WriteBlock(aux->GetSendInfo(), &empty, sizeof(AuxInfoDSP));
memory.WriteBlock(aux->GetRecvInfo(), &empty, sizeof(AuxInfoDSP));
if (output_index != input_index) {
- std::memcpy(GetMixBuffer(output_index), GetMixBuffer(input_index),
+ std::memcpy(GetMixBuffer(output_index).data(), GetMixBuffer(input_index).data(),
worker_params.sample_count * sizeof(s32));
}
}
@@ -665,7 +673,7 @@ ServerSplitterDestinationData* CommandGenerator::GetDestinationData(s32 splitter
}
s32 CommandGenerator::WriteAuxBuffer(AuxInfoDSP& dsp_info, VAddr send_buffer, u32 max_samples,
- const s32* data, u32 sample_count, u32 write_offset,
+ std::span<const s32> data, u32 sample_count, u32 write_offset,
u32 write_count) {
if (max_samples == 0) {
return 0;
@@ -675,14 +683,14 @@ s32 CommandGenerator::WriteAuxBuffer(AuxInfoDSP& dsp_info, VAddr send_buffer, u3
return 0;
}
- std::size_t data_offset{};
+ s32 data_offset{};
u32 remaining = sample_count;
while (remaining > 0) {
// Get position in buffer
const auto base = send_buffer + (offset * sizeof(u32));
const auto samples_to_grab = std::min(max_samples - offset, remaining);
// Write to output
- memory.WriteBlock(base, (data + data_offset), samples_to_grab * sizeof(u32));
+ memory.WriteBlock(base, (data.data() + data_offset), samples_to_grab * sizeof(u32));
offset = (offset + samples_to_grab) % max_samples;
remaining -= samples_to_grab;
data_offset += samples_to_grab;
@@ -695,7 +703,7 @@ s32 CommandGenerator::WriteAuxBuffer(AuxInfoDSP& dsp_info, VAddr send_buffer, u3
}
s32 CommandGenerator::ReadAuxBuffer(AuxInfoDSP& recv_info, VAddr recv_buffer, u32 max_samples,
- s32* out_data, u32 sample_count, u32 read_offset,
+ std::span<s32> out_data, u32 sample_count, u32 read_offset,
u32 read_count) {
if (max_samples == 0) {
return 0;
@@ -707,15 +715,16 @@ s32 CommandGenerator::ReadAuxBuffer(AuxInfoDSP& recv_info, VAddr recv_buffer, u3
}
u32 remaining = sample_count;
+ s32 data_offset{};
while (remaining > 0) {
const auto base = recv_buffer + (offset * sizeof(u32));
const auto samples_to_grab = std::min(max_samples - offset, remaining);
std::vector<s32> buffer(samples_to_grab);
memory.ReadBlock(base, buffer.data(), buffer.size() * sizeof(u32));
- std::memcpy(out_data, buffer.data(), buffer.size() * sizeof(u32));
- out_data += samples_to_grab;
+ std::memcpy(out_data.data() + data_offset, buffer.data(), buffer.size() * sizeof(u32));
offset = (offset + samples_to_grab) % max_samples;
remaining -= samples_to_grab;
+ data_offset += samples_to_grab;
}
if (read_count != 0) {
@@ -795,7 +804,7 @@ void CommandGenerator::UpdateI3dl2Reverb(I3dl2ReverbParams& info, I3dl2ReverbSta
state.lowpass_1 = 0.0f;
} else {
const auto a = 1.0f - hf_gain;
- const auto b = 2.0f * (1.0f - hf_gain * CosD(256.0f * info.hf_reference /
+ const auto b = 2.0f * (2.0f - hf_gain * CosD(256.0f * info.hf_reference /
static_cast<f32>(info.sample_rate)));
const auto c = std::sqrt(b * b - 4.0f * a * a);
@@ -843,7 +852,7 @@ void CommandGenerator::UpdateI3dl2Reverb(I3dl2ReverbParams& info, I3dl2ReverbSta
}
const auto max_early_delay = state.early_delay_line.GetMaxDelay();
- const auto reflection_time = 1000.0f * (0.0098f * info.reverb_delay + 0.02f);
+ const auto reflection_time = 1000.0f * (0.9998f * info.reverb_delay + 0.02f);
for (std::size_t tap = 0; tap < AudioCommon::I3DL2REVERB_TAPS; tap++) {
const auto length = AudioCommon::CalculateDelaySamples(
sample_rate, 1000.0f * info.reflection_delay + reflection_time * EARLY_TAP_TIMES[tap]);
@@ -962,8 +971,8 @@ void CommandGenerator::GenerateMixCommand(std::size_t output_offset, std::size_t
node_id, input_offset, output_offset, volume);
}
- auto* output = GetMixBuffer(output_offset);
- const auto* input = GetMixBuffer(input_offset);
+ std::span<s32> output = GetMixBuffer(output_offset);
+ std::span<const s32> input = GetMixBuffer(input_offset);
const s32 gain = static_cast<s32>(volume * 32768.0f);
// Mix with loop unrolling
@@ -1003,8 +1012,10 @@ void CommandGenerator::GenerateFinalMixCommand() {
}
}
-s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_state,
- s32 sample_count, s32 channel, std::size_t mix_offset) {
+template <typename T>
+s32 CommandGenerator::DecodePcm(ServerVoiceInfo& voice_info, VoiceState& dsp_state,
+ s32 sample_start_offset, s32 sample_end_offset, s32 sample_count,
+ s32 channel, std::size_t mix_offset) {
const auto& in_params = voice_info.GetInParams();
const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index];
if (wave_buffer.buffer_address == 0) {
@@ -1013,39 +1024,50 @@ s32 CommandGenerator::DecodePcm16(ServerVoiceInfo& voice_info, VoiceState& dsp_s
if (wave_buffer.buffer_size == 0) {
return 0;
}
- if (wave_buffer.end_sample_offset < wave_buffer.start_sample_offset) {
+ if (sample_end_offset < sample_start_offset) {
return 0;
}
- const auto samples_remaining =
- (wave_buffer.end_sample_offset - wave_buffer.start_sample_offset) - dsp_state.offset;
+ const auto samples_remaining = (sample_end_offset - sample_start_offset) - dsp_state.offset;
const auto start_offset =
- ((wave_buffer.start_sample_offset + dsp_state.offset) * in_params.channel_count) *
- sizeof(s16);
+ ((dsp_state.offset + sample_start_offset) * in_params.channel_count) * sizeof(T);
const auto buffer_pos = wave_buffer.buffer_address + start_offset;
const auto samples_processed = std::min(sample_count, samples_remaining);
- if (in_params.channel_count == 1) {
- std::vector<s16> buffer(samples_processed);
- memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(s16));
- for (std::size_t i = 0; i < buffer.size(); i++) {
- sample_buffer[mix_offset + i] = buffer[i];
- }
- } else {
- const auto channel_count = in_params.channel_count;
- std::vector<s16> buffer(samples_processed * channel_count);
- memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(s16));
+ const auto channel_count = in_params.channel_count;
+ std::vector<T> buffer(samples_processed * channel_count);
+ memory.ReadBlock(buffer_pos, buffer.data(), buffer.size() * sizeof(T));
+ if constexpr (std::is_floating_point_v<T>) {
+ for (std::size_t i = 0; i < static_cast<std::size_t>(samples_processed); i++) {
+ sample_buffer[mix_offset + i] = static_cast<s32>(buffer[i * channel_count + channel] *
+ std::numeric_limits<s16>::max());
+ }
+ } else if constexpr (sizeof(T) == 1) {
+ for (std::size_t i = 0; i < static_cast<std::size_t>(samples_processed); i++) {
+ sample_buffer[mix_offset + i] =
+ static_cast<s32>(static_cast<f32>(buffer[i * channel_count + channel] /
+ std::numeric_limits<s8>::max()) *
+ std::numeric_limits<s16>::max());
+ }
+ } else if constexpr (sizeof(T) == 2) {
for (std::size_t i = 0; i < static_cast<std::size_t>(samples_processed); i++) {
sample_buffer[mix_offset + i] = buffer[i * channel_count + channel];
}
+ } else {
+ for (std::size_t i = 0; i < static_cast<std::size_t>(samples_processed); i++) {
+ sample_buffer[mix_offset + i] =
+ static_cast<s32>(static_cast<f32>(buffer[i * channel_count + channel] /
+ std::numeric_limits<s32>::max()) *
+ std::numeric_limits<s16>::max());
+ }
}
return samples_processed;
}
s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_state,
- s32 sample_count, [[maybe_unused]] s32 channel,
- std::size_t mix_offset) {
+ s32 sample_start_offset, s32 sample_end_offset, s32 sample_count,
+ [[maybe_unused]] s32 channel, std::size_t mix_offset) {
const auto& in_params = voice_info.GetInParams();
const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index];
if (wave_buffer.buffer_address == 0) {
@@ -1054,7 +1076,7 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s
if (wave_buffer.buffer_size == 0) {
return 0;
}
- if (wave_buffer.end_sample_offset < wave_buffer.start_sample_offset) {
+ if (sample_end_offset < sample_start_offset) {
return 0;
}
@@ -1079,10 +1101,9 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s
s32 coef1 = coeffs[idx * 2];
s32 coef2 = coeffs[idx * 2 + 1];
- const auto samples_remaining =
- (wave_buffer.end_sample_offset - wave_buffer.start_sample_offset) - dsp_state.offset;
+ const auto samples_remaining = (sample_end_offset - sample_start_offset) - dsp_state.offset;
const auto samples_processed = std::min(sample_count, samples_remaining);
- const auto sample_pos = wave_buffer.start_sample_offset + dsp_state.offset;
+ const auto sample_pos = dsp_state.offset + sample_start_offset;
const auto samples_remaining_in_frame = sample_pos % SAMPLES_PER_FRAME;
auto position_in_frame = ((sample_pos / SAMPLES_PER_FRAME) * NIBBLES_PER_SAMPLE) +
@@ -1157,12 +1178,14 @@ s32 CommandGenerator::DecodeAdpcm(ServerVoiceInfo& voice_info, VoiceState& dsp_s
return samples_processed;
}
-s32* CommandGenerator::GetMixBuffer(std::size_t index) {
- return mix_buffer.data() + (index * worker_params.sample_count);
+std::span<s32> CommandGenerator::GetMixBuffer(std::size_t index) {
+ return std::span<s32>(mix_buffer.data() + (index * worker_params.sample_count),
+ worker_params.sample_count);
}
-const s32* CommandGenerator::GetMixBuffer(std::size_t index) const {
- return mix_buffer.data() + (index * worker_params.sample_count);
+std::span<const s32> CommandGenerator::GetMixBuffer(std::size_t index) const {
+ return std::span<const s32>(mix_buffer.data() + (index * worker_params.sample_count),
+ worker_params.sample_count);
}
std::size_t CommandGenerator::GetMixChannelBufferOffset(s32 channel) const {
@@ -1173,15 +1196,15 @@ std::size_t CommandGenerator::GetTotalMixBufferCount() const {
return worker_params.mix_buffer_count + AudioCommon::MAX_CHANNEL_COUNT;
}
-s32* CommandGenerator::GetChannelMixBuffer(s32 channel) {
+std::span<s32> CommandGenerator::GetChannelMixBuffer(s32 channel) {
return GetMixBuffer(worker_params.mix_buffer_count + channel);
}
-const s32* CommandGenerator::GetChannelMixBuffer(s32 channel) const {
+std::span<const s32> CommandGenerator::GetChannelMixBuffer(s32 channel) const {
return GetMixBuffer(worker_params.mix_buffer_count + channel);
}
-void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* output,
+void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, std::span<s32> output,
VoiceState& dsp_state, s32 channel,
s32 target_sample_rate, s32 sample_count,
s32 node_id) {
@@ -1193,7 +1216,7 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o
node_id, channel, in_params.sample_format, sample_count, in_params.sample_rate,
in_params.mix_id, in_params.splitter_info_id);
}
- ASSERT_OR_EXECUTE(output != nullptr, { return; });
+ ASSERT_OR_EXECUTE(output.data() != nullptr, { return; });
const auto resample_rate = static_cast<s32>(
static_cast<float>(in_params.sample_rate) / static_cast<float>(target_sample_rate) *
@@ -1210,9 +1233,9 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o
}
std::size_t temp_mix_offset{};
- bool is_buffer_completed{false};
+ s32 samples_output{};
auto samples_remaining = sample_count;
- while (samples_remaining > 0 && !is_buffer_completed) {
+ while (samples_remaining > 0) {
const auto samples_to_output = std::min(samples_remaining, min_required_samples);
const auto samples_to_read = (samples_to_output * resample_rate + dsp_state.fraction) >> 15;
@@ -1229,24 +1252,53 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o
const auto& wave_buffer = in_params.wave_buffer[dsp_state.wave_buffer_index];
// No more data can be read
if (!dsp_state.is_wave_buffer_valid[dsp_state.wave_buffer_index]) {
- is_buffer_completed = true;
break;
}
if (in_params.sample_format == SampleFormat::Adpcm && dsp_state.offset == 0 &&
wave_buffer.context_address != 0 && wave_buffer.context_size != 0) {
- // TODO(ogniK): ADPCM loop context
+ memory.ReadBlock(wave_buffer.context_address, &dsp_state.context,
+ sizeof(ADPCMContext));
+ }
+
+ s32 samples_offset_start;
+ s32 samples_offset_end;
+ if (dsp_state.loop_count > 0 && wave_buffer.loop_start_sample != 0 &&
+ wave_buffer.loop_end_sample != 0 &&
+ wave_buffer.loop_start_sample <= wave_buffer.loop_end_sample) {
+ samples_offset_start = wave_buffer.loop_start_sample;
+ samples_offset_end = wave_buffer.loop_end_sample;
+ } else {
+ samples_offset_start = wave_buffer.start_sample_offset;
+ samples_offset_end = wave_buffer.end_sample_offset;
}
s32 samples_decoded{0};
switch (in_params.sample_format) {
+ case SampleFormat::Pcm8:
+ samples_decoded =
+ DecodePcm<s8>(voice_info, dsp_state, samples_offset_start, samples_offset_end,
+ samples_to_read - samples_read, channel, temp_mix_offset);
+ break;
case SampleFormat::Pcm16:
- samples_decoded = DecodePcm16(voice_info, dsp_state, samples_to_read - samples_read,
- channel, temp_mix_offset);
+ samples_decoded =
+ DecodePcm<s16>(voice_info, dsp_state, samples_offset_start, samples_offset_end,
+ samples_to_read - samples_read, channel, temp_mix_offset);
+ break;
+ case SampleFormat::Pcm32:
+ samples_decoded =
+ DecodePcm<s32>(voice_info, dsp_state, samples_offset_start, samples_offset_end,
+ samples_to_read - samples_read, channel, temp_mix_offset);
+ break;
+ case SampleFormat::PcmFloat:
+ samples_decoded =
+ DecodePcm<f32>(voice_info, dsp_state, samples_offset_start, samples_offset_end,
+ samples_to_read - samples_read, channel, temp_mix_offset);
break;
case SampleFormat::Adpcm:
- samples_decoded = DecodeAdpcm(voice_info, dsp_state, samples_to_read - samples_read,
- channel, temp_mix_offset);
+ samples_decoded =
+ DecodeAdpcm(voice_info, dsp_state, samples_offset_start, samples_offset_end,
+ samples_to_read - samples_read, channel, temp_mix_offset);
break;
default:
UNREACHABLE_MSG("Unimplemented sample format={}", in_params.sample_format);
@@ -1257,15 +1309,19 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o
dsp_state.offset += samples_decoded;
dsp_state.played_sample_count += samples_decoded;
- if (dsp_state.offset >=
- (wave_buffer.end_sample_offset - wave_buffer.start_sample_offset) ||
+ if (dsp_state.offset >= (samples_offset_end - samples_offset_start) ||
samples_decoded == 0) {
// Reset our sample offset
dsp_state.offset = 0;
if (wave_buffer.is_looping) {
- if (samples_decoded == 0) {
+ dsp_state.loop_count++;
+ if (wave_buffer.loop_count > 0 &&
+ (dsp_state.loop_count > wave_buffer.loop_count || samples_decoded == 0)) {
// End of our buffer
- is_buffer_completed = true;
+ voice_info.SetWaveBufferCompleted(dsp_state, wave_buffer);
+ }
+
+ if (samples_decoded == 0) {
break;
}
@@ -1273,35 +1329,29 @@ void CommandGenerator::DecodeFromWaveBuffers(ServerVoiceInfo& voice_info, s32* o
dsp_state.played_sample_count = 0;
}
} else {
-
// Update our wave buffer states
- dsp_state.is_wave_buffer_valid[dsp_state.wave_buffer_index] = false;
- dsp_state.wave_buffer_consumed++;
- dsp_state.wave_buffer_index =
- (dsp_state.wave_buffer_index + 1) % AudioCommon::MAX_WAVE_BUFFERS;
- if (wave_buffer.end_of_stream) {
- dsp_state.played_sample_count = 0;
- }
+ voice_info.SetWaveBufferCompleted(dsp_state, wave_buffer);
}
}
}
if (in_params.behavior_flags.is_pitch_and_src_skipped.Value()) {
// No need to resample
- std::memcpy(output, sample_buffer.data(), samples_read * sizeof(s32));
+ std::memcpy(output.data() + samples_output, sample_buffer.data(),
+ samples_read * sizeof(s32));
} else {
std::fill(sample_buffer.begin() + temp_mix_offset,
sample_buffer.begin() + temp_mix_offset + (samples_to_read - samples_read),
0);
- AudioCore::Resample(output, sample_buffer.data(), resample_rate, dsp_state.fraction,
- samples_to_output);
+ AudioCore::Resample(output.data() + samples_output, sample_buffer.data(), resample_rate,
+ dsp_state.fraction, samples_to_output);
// Resample
for (std::size_t i = 0; i < AudioCommon::MAX_SAMPLE_HISTORY; i++) {
dsp_state.sample_history[i] = sample_buffer[samples_to_read + i];
}
}
- output += samples_to_output;
samples_remaining -= samples_to_output;
+ samples_output += samples_to_output;
}
}