mirror of
https://github.com/Zelda64Recomp/Zelda64Recomp.git
synced 2026-04-29 05:31:47 +00:00
try surround sound
This commit is contained in:
parent
b31cf0a76b
commit
4e329c4efa
1 changed files with 54 additions and 13 deletions
|
|
@ -192,36 +192,70 @@ void queue_samples(int16_t* audio_data, size_t sample_count) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the duplicated frames from last chunk into this chunk
|
// Copy the duplicated frames from last chunk into this chunk
|
||||||
for (size_t i = 0; i < duplicated_input_frames * input_channels; i++) {
|
copy_duplicated_frames(swap_buffer, duplicated_sample_buffer);
|
||||||
swap_buffer[i] = duplicated_sample_buffer[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert the audio from 16-bit values to floats and swap the audio channels into the
|
// Convert the audio from 16-bit values to floats and swap the audio channels into the
|
||||||
// swap buffer to correct for the address xor caused by endianness handling.
|
// swap buffer to correct for the address XOR caused by endianness handling.
|
||||||
float cur_main_volume = zelda64::get_main_volume() / 100.0f; // Get the current main volume, normalized to 0.0-1.0.
|
convert_and_swap_channels(audio_data, sample_count, swap_buffer);
|
||||||
for (size_t i = 0; i < sample_count; i += input_channels) {
|
|
||||||
swap_buffer[i + 0 + duplicated_input_frames * input_channels] = audio_data[i + 1] * (0.5f / 32768.0f) * cur_main_volume;
|
|
||||||
swap_buffer[i + 1 + duplicated_input_frames * input_channels] = audio_data[i + 0] * (0.5f / 32768.0f) * cur_main_volume;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO handle cases where a chunk is smaller than the duplicated frame count.
|
// TODO handle cases where a chunk is smaller than the duplicated frame count.
|
||||||
assert(sample_count > duplicated_input_frames * input_channels);
|
assert(sample_count > duplicated_input_frames * input_channels);
|
||||||
|
|
||||||
// Copy the last converted samples into the duplicated sample buffer to reuse in resampling the next queued chunk.
|
// Copy the last converted samples into the duplicated sample buffer to reuse in resampling the next queued chunk.
|
||||||
|
copy_last_samples(swap_buffer, sample_count, duplicated_sample_buffer);
|
||||||
|
|
||||||
|
// Set up the SDL audio converter
|
||||||
|
prepare_audio_converter(swap_buffer, sample_count);
|
||||||
|
|
||||||
|
// Convert the audio to the output format.
|
||||||
|
convert_audio();
|
||||||
|
|
||||||
|
// Queue the converted audio to the device.
|
||||||
|
queue_audio_data(swap_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy_duplicated_frames(std::vector<float>& swap_buffer, const std::array<float, duplicated_input_frames * input_channels>& duplicated_sample_buffer) {
|
||||||
|
for (size_t i = 0; i < duplicated_input_frames * input_channels; i++) {
|
||||||
|
swap_buffer[i] = duplicated_sample_buffer[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void convert_and_swap_channels(int16_t* audio_data, size_t sample_count, std::vector<float>& swap_buffer) {
|
||||||
|
float cur_main_volume = zelda64::get_main_volume() / 100.0f; // Get the current main volume, normalized to 0.0-1.0.
|
||||||
|
for (size_t i = 0; i < sample_count; i += input_channels) {
|
||||||
|
if (input_channels == 2) { // Stereo
|
||||||
|
swap_buffer[i + 0 + duplicated_input_frames * input_channels] = audio_data[i + 1] * (0.5f / 32768.0f) * cur_main_volume;
|
||||||
|
swap_buffer[i + 1 + duplicated_input_frames * input_channels] = audio_data[i + 0] * (0.5f / 32768.0f) * cur_main_volume;
|
||||||
|
} else if (input_channels == 4) { // Quadraphonic
|
||||||
|
swap_buffer[i + 0 + duplicated_input_frames * input_channels] = audio_data[i + 3] * (0.5f / 32768.0f) * cur_main_volume; // Rear left
|
||||||
|
swap_buffer[i + 1 + duplicated_input_frames * input_channels] = audio_data[i + 2] * (0.5f / 32768.0f) * cur_main_volume; // Rear right
|
||||||
|
swap_buffer[i + 2 + duplicated_input_frames * input_channels] = audio_data[i + 1] * (0.5f / 32768.0f) * cur_main_volume; // Front left
|
||||||
|
swap_buffer[i + 3 + duplicated_input_frames * input_channels] = audio_data[i + 0] * (0.5f / 32768.0f) * cur_main_volume; // Front right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy_last_samples(std::vector<float>& swap_buffer, size_t sample_count, std::array<float, duplicated_input_frames * input_channels>& duplicated_sample_buffer) {
|
||||||
for (size_t i = 0; i < duplicated_input_frames * input_channels; i++) {
|
for (size_t i = 0; i < duplicated_input_frames * input_channels; i++) {
|
||||||
duplicated_sample_buffer[i] = swap_buffer[i + sample_count];
|
duplicated_sample_buffer[i] = swap_buffer[i + sample_count];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void prepare_audio_converter(std::vector<float>& swap_buffer, size_t sample_count) {
|
||||||
audio_convert.buf = reinterpret_cast<Uint8*>(swap_buffer.data());
|
audio_convert.buf = reinterpret_cast<Uint8*>(swap_buffer.data());
|
||||||
audio_convert.len = (sample_count + duplicated_input_frames * input_channels) * sizeof(swap_buffer[0]);
|
audio_convert.len = (sample_count + duplicated_input_frames * input_channels) * sizeof(swap_buffer[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void convert_audio() {
|
||||||
int ret = SDL_ConvertAudio(&audio_convert);
|
int ret = SDL_ConvertAudio(&audio_convert);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
printf("Error using SDL audio converter: %s\n", SDL_GetError());
|
printf("Error using SDL audio converter: %s\n", SDL_GetError());
|
||||||
throw std::runtime_error("Error using SDL audio converter");
|
throw std::runtime_error("Error using SDL audio converter");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void queue_audio_data(std::vector<float>& swap_buffer) {
|
||||||
uint64_t cur_queued_microseconds = uint64_t(SDL_GetQueuedAudioSize(audio_device)) / bytes_per_frame * 1000000 / sample_rate;
|
uint64_t cur_queued_microseconds = uint64_t(SDL_GetQueuedAudioSize(audio_device)) / bytes_per_frame * 1000000 / sample_rate;
|
||||||
uint32_t num_bytes_to_queue = audio_convert.len_cvt - output_channels * discarded_output_frames * sizeof(swap_buffer[0]);
|
uint32_t num_bytes_to_queue = audio_convert.len_cvt - output_channels * discarded_output_frames * sizeof(swap_buffer[0]);
|
||||||
float* samples_to_queue = swap_buffer.data() + output_channels * discarded_output_frames / 2;
|
float* samples_to_queue = swap_buffer.data() + output_channels * discarded_output_frames / 2;
|
||||||
|
|
@ -233,8 +267,15 @@ void queue_samples(int16_t* audio_data, size_t sample_count) {
|
||||||
uint32_t skip_ratio = 1 << skip_factor;
|
uint32_t skip_ratio = 1 << skip_factor;
|
||||||
num_bytes_to_queue /= skip_ratio;
|
num_bytes_to_queue /= skip_ratio;
|
||||||
for (size_t i = 0; i < num_bytes_to_queue / (output_channels * sizeof(swap_buffer[0])); i++) {
|
for (size_t i = 0; i < num_bytes_to_queue / (output_channels * sizeof(swap_buffer[0])); i++) {
|
||||||
samples_to_queue[2 * i + 0] = samples_to_queue[2 * skip_ratio * i + 0];
|
if (input_channels == 2) {
|
||||||
samples_to_queue[2 * i + 1] = samples_to_queue[2 * skip_ratio * i + 1];
|
samples_to_queue[2 * i + 0] = samples_to_queue[2 * skip_ratio * i + 0];
|
||||||
|
samples_to_queue[2 * i + 1] = samples_to_queue[2 * skip_ratio * i + 1];
|
||||||
|
} else if (input_channels == 4) {
|
||||||
|
samples_to_queue[4 * i + 0] = samples_to_queue[4 * skip_ratio * i + 0]; // Rear left
|
||||||
|
samples_to_queue[4 * i + 1] = samples_to_queue[4 * skip_ratio * i + 1]; // Rear right
|
||||||
|
samples_to_queue[4 * i + 2] = samples_to_queue[4 * skip_ratio * i + 2]; // Front left
|
||||||
|
samples_to_queue[4 * i + 3] = samples_to_queue[4 * skip_ratio * i + 3]; // Front right
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue