[APU] XMA: Fix audio loop handling.
Handles audio loop if loop_start < loop_end. Need to handle additional cases like loop_start > loop_end.
This commit is contained in:
parent
1d51b574ec
commit
372bdd3ec9
|
@ -177,6 +177,25 @@ void XmaContext::SwapInputBuffer(XMA_CONTEXT_DATA* data) {
|
||||||
data->input_buffer_read_offset = 0;
|
data->input_buffer_read_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool XmaContext::TrySetupNextLoop(XMA_CONTEXT_DATA* data,
|
||||||
|
bool ignore_input_buffer_offset) {
|
||||||
|
// Setup the input buffer offset if next loop exists.
|
||||||
|
// TODO(Pseudo-Kernel): Need to handle loop in the following cases.
|
||||||
|
// 1. loop_start == loop_end == 0
|
||||||
|
// 2. loop_start > loop_end && loop_count > 0
|
||||||
|
if (data->loop_count > 0 && data->loop_start < data->loop_end &&
|
||||||
|
(ignore_input_buffer_offset ||
|
||||||
|
data->input_buffer_read_offset >= data->loop_end)) {
|
||||||
|
// Loop back to the beginning.
|
||||||
|
data->input_buffer_read_offset = data->loop_start;
|
||||||
|
if (data->loop_count < 255) {
|
||||||
|
data->loop_count--;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
void XmaContext::NextPacket(
|
void XmaContext::NextPacket(
|
||||||
uint8_t* input_buffer,
|
uint8_t* input_buffer,
|
||||||
|
@ -364,6 +383,7 @@ void XmaContext::Decode(XMA_CONTEXT_DATA* data) {
|
||||||
assert_false(data->stop_when_done);
|
assert_false(data->stop_when_done);
|
||||||
assert_false(data->interrupt_when_done);
|
assert_false(data->interrupt_when_done);
|
||||||
static int total_samples = 0;
|
static int total_samples = 0;
|
||||||
|
bool reuse_input_buffer = false;
|
||||||
// Decode until we can't write any more data.
|
// Decode until we can't write any more data.
|
||||||
while (output_remaining_bytes > 0) {
|
while (output_remaining_bytes > 0) {
|
||||||
if (!data->input_buffer_0_valid && !data->input_buffer_1_valid) {
|
if (!data->input_buffer_0_valid && !data->input_buffer_1_valid) {
|
||||||
|
@ -371,6 +391,10 @@ void XmaContext::Decode(XMA_CONTEXT_DATA* data) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup the input buffer if we are at loop_end.
|
||||||
|
// The input buffer must not be swapped out until all loops are processed.
|
||||||
|
reuse_input_buffer = TrySetupNextLoop(data, false);
|
||||||
|
|
||||||
// assert_true(packets_skip_ == 0);
|
// assert_true(packets_skip_ == 0);
|
||||||
// assert_true(split_frame_len_ == 0);
|
// assert_true(split_frame_len_ == 0);
|
||||||
// assert_true(split_frame_len_partial_ == 0);
|
// assert_true(split_frame_len_partial_ == 0);
|
||||||
|
@ -392,7 +416,13 @@ void XmaContext::Decode(XMA_CONTEXT_DATA* data) {
|
||||||
packets_skip_--;
|
packets_skip_--;
|
||||||
packet_idx++;
|
packet_idx++;
|
||||||
if (packet_idx >= current_input_packet_count) {
|
if (packet_idx >= current_input_packet_count) {
|
||||||
SwapInputBuffer(data);
|
if (!reuse_input_buffer) {
|
||||||
|
// Last packet. Try setup once more.
|
||||||
|
reuse_input_buffer = TrySetupNextLoop(data, true);
|
||||||
|
}
|
||||||
|
if (!reuse_input_buffer) {
|
||||||
|
SwapInputBuffer(data);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -524,7 +554,13 @@ void XmaContext::Decode(XMA_CONTEXT_DATA* data) {
|
||||||
packet += kBytesPerPacket;
|
packet += kBytesPerPacket;
|
||||||
packet_idx++;
|
packet_idx++;
|
||||||
if (packet_idx >= current_input_packet_count) {
|
if (packet_idx >= current_input_packet_count) {
|
||||||
SwapInputBuffer(data);
|
if (!reuse_input_buffer) {
|
||||||
|
// Last packet. Try setup once more.
|
||||||
|
reuse_input_buffer = TrySetupNextLoop(data, true);
|
||||||
|
}
|
||||||
|
if (!reuse_input_buffer) {
|
||||||
|
SwapInputBuffer(data);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -606,7 +642,13 @@ void XmaContext::Decode(XMA_CONTEXT_DATA* data) {
|
||||||
packets_skip_--;
|
packets_skip_--;
|
||||||
packet_idx++;
|
packet_idx++;
|
||||||
if (packet_idx >= current_input_packet_count) {
|
if (packet_idx >= current_input_packet_count) {
|
||||||
SwapInputBuffer(data);
|
if (!reuse_input_buffer) {
|
||||||
|
// Last packet. Try setup once more.
|
||||||
|
reuse_input_buffer = TrySetupNextLoop(data, true);
|
||||||
|
}
|
||||||
|
if (!reuse_input_buffer) {
|
||||||
|
SwapInputBuffer(data);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -618,7 +660,13 @@ void XmaContext::Decode(XMA_CONTEXT_DATA* data) {
|
||||||
// Next packet but we already skipped to it
|
// Next packet but we already skipped to it
|
||||||
if (packet_idx >= current_input_packet_count) {
|
if (packet_idx >= current_input_packet_count) {
|
||||||
// Buffer is fully used
|
// Buffer is fully used
|
||||||
SwapInputBuffer(data);
|
if (!reuse_input_buffer) {
|
||||||
|
// Last packet. Try setup once more.
|
||||||
|
reuse_input_buffer = TrySetupNextLoop(data, true);
|
||||||
|
}
|
||||||
|
if (!reuse_input_buffer) {
|
||||||
|
SwapInputBuffer(data);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
offset =
|
offset =
|
||||||
|
|
|
@ -171,6 +171,8 @@ class XmaContext {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void SwapInputBuffer(XMA_CONTEXT_DATA* data);
|
static void SwapInputBuffer(XMA_CONTEXT_DATA* data);
|
||||||
|
static bool TrySetupNextLoop(XMA_CONTEXT_DATA* data,
|
||||||
|
bool ignore_input_buffer_offset);
|
||||||
static void NextPacket(XMA_CONTEXT_DATA* data);
|
static void NextPacket(XMA_CONTEXT_DATA* data);
|
||||||
static int GetSampleRate(int id);
|
static int GetSampleRate(int id);
|
||||||
// Get the offset of the next frame. Does not traverse packets.
|
// Get the offset of the next frame. Does not traverse packets.
|
||||||
|
|
Loading…
Reference in New Issue