Improve audio poppings

This commit is contained in:
Lorenzooone 2024-06-24 04:21:10 +02:00
parent 4f6998ab33
commit 7d831d2911
8 changed files with 61 additions and 17 deletions

View File

@ -14,6 +14,8 @@ enum AudioMenuOutAction{
AUDIO_MENU_MUTE,
AUDIO_MENU_VOLUME_DEC,
AUDIO_MENU_VOLUME_INC,
AUDIO_MENU_MAX_LATENCY_DEC,
AUDIO_MENU_MAX_LATENCY_INC,
AUDIO_MENU_RESTART,
};

View File

@ -2,14 +2,17 @@
#define __AUDIO_DATA_HPP
#include <string>
#define MAX_MAX_AUDIO_LATENCY 10
class AudioData {
public:
void reset();
void set_max_audio_latency(int new_value);
void change_audio_volume(bool is_change_positive);
void change_audio_mute();
void request_audio_restart();
bool check_audio_restart_request();
int get_max_audio_latency();
int get_final_volume();
bool has_text_to_print();
std::string text_to_print();
@ -20,6 +23,7 @@ public:
private:
int volume;
int max_audio_latency;
bool mute;
bool restart_request = false;
bool text_updated;
@ -27,6 +31,7 @@ private:
void set_audio_volume(int new_volume);
void set_audio_mute(bool new_mute);
void update_text(std::string text);
const std::string max_audio_latency_str = "max_audio_latency";
const std::string volume_str = "volume";
const std::string mute_str = "mute";
};

View File

@ -64,9 +64,12 @@
#define MAX_IN_VIDEO_SIZE (MAX_IN_VIDEO_WIDTH * MAX_IN_VIDEO_HEIGHT)
#define MAX_IN_VIDEO_BPP_SIZE IN_VIDEO_BPP_SIZE_3DS
#define O3DS_SAMPLES_IN (1096 * 8) // This one can go beyond the normal amount, so factor in a buffer of sorts. 8x is way more than needed, but better being safe than sorry!
#define N3DSXL_SAMPLES_IN 1096
#define DS_SAMPLES_IN 1096
// 1096 is the value when things are ideal. However, it can actually happen that the transfer isn't 100% on time.
// When that happens, a bit more audio data may get transfered. It's a ton on O3DS when Windows underprioritizes USB...
// In general, it should be less than * 2, but you never know. For now, go for safety at x16...
#define O3DS_SAMPLES_IN (1096 * 16)
#define N3DSXL_SAMPLES_IN (1096 * 16)
#define DS_SAMPLES_IN (1096 * 16)
#define MAX_SAMPLES_IN O3DS_SAMPLES_IN
#endif

View File

@ -22,6 +22,11 @@ static const AudioMenuOptionInfo audio_mute_option = {
.is_inc = false, .dec_str = "", .inc_str = "", .inc_out_action = AUDIO_MENU_NO_ACTION,
.out_action = AUDIO_MENU_MUTE};
static const AudioMenuOptionInfo audio_max_latency_option = {
.base_name = "Max Latency", .false_name = "",
.is_inc = true, .dec_str = "-", .inc_str = "+", .inc_out_action = AUDIO_MENU_MAX_LATENCY_INC,
.out_action = AUDIO_MENU_MAX_LATENCY_DEC};
static const AudioMenuOptionInfo audio_restart_option = {
.base_name = "Restart Audio", .false_name = "",
.is_inc = false, .dec_str = "", .inc_str = "", .inc_out_action = AUDIO_MENU_NO_ACTION,
@ -30,6 +35,7 @@ static const AudioMenuOptionInfo audio_restart_option = {
static const AudioMenuOptionInfo* pollable_options[] = {
&audio_volume_option,
&audio_mute_option,
&audio_max_latency_option,
&audio_restart_option,
};
@ -114,6 +120,9 @@ void AudioMenu::prepare(float menu_scaling_factor, int view_size_x, int view_siz
case AUDIO_MENU_VOLUME_DEC:
this->labels[index]->setText(this->setTextOptionInt(real_index, audio_data->get_real_volume()));
break;
case AUDIO_MENU_MAX_LATENCY_DEC:
this->labels[index]->setText(this->setTextOptionInt(real_index, audio_data->get_max_audio_latency()));
break;
case AUDIO_MENU_MUTE:
this->labels[index]->setText(this->setTextOptionBool(real_index, audio_data->get_mute()));
break;

View File

@ -1176,6 +1176,12 @@ void WindowScreen::poll(bool do_everything) {
case AUDIO_MENU_VOLUME_INC:
this->audio_data->change_audio_volume(true);
break;
case AUDIO_MENU_MAX_LATENCY_DEC:
this->audio_data->set_max_audio_latency(this->audio_data->get_max_audio_latency() - 1);
break;
case AUDIO_MENU_MAX_LATENCY_INC:
this->audio_data->set_max_audio_latency(this->audio_data->get_max_audio_latency() + 1);
break;
case AUDIO_MENU_MUTE:
this->audio_data->change_audio_mute();
break;

View File

@ -17,7 +17,7 @@ Sample::Sample(sf::Int16 *bytes, std::size_t size, float time) : bytes(bytes), s
Audio::Audio(AudioData *audio_data) {
this->audio_data = audio_data;
// Consume old events
this->buffer = new sf::Int16[MAX_SAMPLES_IN];
this->buffer = new sf::Int16[MAX_SAMPLES_IN * (MAX_MAX_AUDIO_LATENCY + 1)];
this->audio_data->check_audio_restart_request();
sf::SoundStream::initialize(AUDIO_CHANNELS, SAMPLE_RATE);
this->setPitch(PITCH_RATE);
@ -80,21 +80,22 @@ bool Audio::onGetData(sf::SoundStream::Chunk &data) {
}
data.samples = (const sf::Int16*)buffer;
while(loaded_samples > 2) {
while(loaded_samples > this->audio_data->get_max_audio_latency()) {
samples.pop();
loaded_samples = samples.size();
}
const sf::Int16 *data_samples = samples.front().bytes;
int count = samples.front().size;
memcpy(buffer, data_samples, count * sizeof(sf::Int16));
data.sampleCount = 0;
data.sampleCount = count;
// Unused, but could be useful info
//double real_sample_rate = (1.0 / samples.front().time) * count / 2;
samples.pop();
for(int i = 0; i < loaded_samples; i++) {
const sf::Int16 *data_samples = samples.front().bytes;
int count = samples.front().size;
memcpy(buffer + data.sampleCount, data_samples, count * sizeof(sf::Int16));
// Unused, but could be useful info
//double real_sample_rate = (1.0 / samples.front().time) * count / 2;
data.sampleCount += count;
samples.pop();
}
// Basically, look into how low the time between calls of the function is
curr_time = std::chrono::high_resolution_clock::now();

View File

@ -3,10 +3,20 @@
void AudioData::reset() {
this->volume = 50;
this->mute = false;
this->max_audio_latency = 2;
this->restart_request = false;
this->text_updated = false;
}
void AudioData::set_max_audio_latency(int new_value) {
if(new_value > MAX_MAX_AUDIO_LATENCY)
new_value = MAX_MAX_AUDIO_LATENCY;
if(new_value <= 0)
new_value = 1;
this->max_audio_latency = new_value;
}
void AudioData::change_audio_volume(bool is_change_positive) {
bool initial_audio_mute = this->mute;
int initial_audio_volume = this->volume;
@ -55,6 +65,10 @@ std::string AudioData::text_to_print() {
return this->text;
}
int AudioData::get_max_audio_latency() {
return this->max_audio_latency;
}
int AudioData::get_final_volume() {
if(this->mute)
return 0;
@ -88,6 +102,10 @@ bool AudioData::load_audio_data(std::string key, std::string value) {
this->set_audio_volume(std::stoi(value));
return true;
}
if (key == this->max_audio_latency_str) {
this->set_max_audio_latency(std::stoi(value));
return true;
}
return false;
}
@ -95,6 +113,7 @@ std::string AudioData::save_audio_data() {
std::string out_str = "";
out_str += this->mute_str + "=" + std::to_string(this->mute) + "\n";
out_str += this->volume_str + "=" + std::to_string(this->volume) + "\n";
out_str += this->max_audio_latency_str + "=" + std::to_string(this->max_audio_latency) + "\n";
return out_str;
}

View File

@ -26,8 +26,7 @@
#include "conversions.hpp"
// Threshold to keep the audio latency limited in "amount of frames".
#define AUDIO_LATENCY_LIMIT 4
#define NUM_CONCURRENT_AUDIO_BUFFERS ((AUDIO_LATENCY_LIMIT * 2) + 1)
#define NUM_CONCURRENT_AUDIO_BUFFERS ((MAX_MAX_AUDIO_LATENCY * 2) + 1)
struct OutTextData {
std::string full_text;
@ -220,7 +219,7 @@ static void soundCall(AudioData *audio_data, CaptureData* capture_data) {
if((!capture_data->status.cooldown_curr_in) && (curr_out != prev_out)) {
loaded_samples = audio.samples.size();
if((capture_data->read[curr_out] > get_video_in_size(capture_data)) && (loaded_samples < AUDIO_LATENCY_LIMIT)) {
if((capture_data->read[curr_out] > get_video_in_size(capture_data)) && (loaded_samples < MAX_MAX_AUDIO_LATENCY)) {
int n_samples = get_audio_n_samples(capture_data, capture_data->read[curr_out]);
double out_time = capture_data->time_in_buf[curr_out];
convertAudioToOutput(&capture_data->capture_buf[curr_out], out_buf[audio_buf_counter], n_samples, endianness, capture_data);