Separate AudioData from Audio, and increase information printed to user

This commit is contained in:
Lorenzooone 2024-04-25 19:44:54 +02:00
parent 6c241928e6
commit a05ed0445b
9 changed files with 179 additions and 88 deletions

View File

@ -84,7 +84,7 @@ set(OUTPUT_NAME cc3dsfs)
add_custom_target(CMakeFTD3XX)
add_custom_target(CMakeBin2C)
add_executable(${OUTPUT_NAME} source/cc3dsfs.cpp source/utils.cpp source/audio.cpp source/frontend.cpp source/TextRectangle.cpp source/WindowScreen.cpp source/3dscapture.cpp source/conversions.cpp ${TOOLS_DATA_DIR}/font_ttf.cpp)
add_executable(${OUTPUT_NAME} source/cc3dsfs.cpp source/utils.cpp source/audio_data.cpp source/audio.cpp source/frontend.cpp source/TextRectangle.cpp source/WindowScreen.cpp source/3dscapture.cpp source/conversions.cpp ${TOOLS_DATA_DIR}/font_ttf.cpp)
add_dependencies(${OUTPUT_NAME} CMakeFTD3XX)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
target_link_libraries(${OUTPUT_NAME} PRIVATE sfml-graphics sfml-audio sfml-window sfml-system FTD3XX)

View File

@ -3,16 +3,12 @@
#include <SFML/Audio.hpp>
#include <queue>
#include "audio_data.hpp"
#include "utils.hpp"
#include "audio.hpp"
#include "3dscapture.hpp"
#include "hw_defs.hpp"
struct AudioData {
int volume;
bool mute;
};
struct Sample {
Sample(sf::Int16 *bytes, std::size_t size, float time);
@ -27,14 +23,14 @@ public:
std::queue<Sample> samples;
ConsumerMutex samples_wait;
Audio();
void update_volume(int volume, bool mute);
Audio(AudioData *audio_data);
void update_volume();
void start_audio();
void stop_audio();
private:
int loaded_volume = -1;
bool loaded_mute = false;
AudioData *audio_data;
int final_volume = -1;
bool terminate;
int num_consecutive_fast_seek;
sf::Int16 buffer[MAX_SAMPLES_IN];

28
include/audio_data.hpp Executable file
View File

@ -0,0 +1,28 @@
#ifndef __AUDIO_DATA_HPP
#define __AUDIO_DATA_HPP
#include <string>
class AudioData {
public:
void reset();
void change_audio_volume(bool is_change_positive);
void change_audio_mute();
int get_final_volume();
bool has_text_to_print();
std::string text_to_print();
int get_real_volume();
bool load_audio_data(std::string key, std::string value);
std::string save_audio_data();
private:
int volume;
bool mute;
bool text_updated;
void set_audio_volume(int new_volume);
void set_audio_mute(bool new_mute);
const std::string volume_str = "volume";
const std::string mute_str = "mute";
};
#endif

View File

@ -4,8 +4,11 @@
#include <SFML/Graphics.hpp>
#include <mutex>
#include <queue>
#include "utils.hpp"
#include "audio.hpp"
#include "audio_data.hpp"
#include "3dscapture.hpp"
#include "hw_defs.hpp"
enum Crop { DEFAULT_3DS, SPECIAL_DS, SCALED_DS, NATIVE_DS, SCALED_GBA, NATIVE_GBA, SCALED_GB, NATIVE_GB, NATIVE_SNES, NATIVE_NES, CROP_END };
enum BottomRelativePosition { UNDER_TOP, LEFT_TOP, ABOVE_TOP, RIGHT_TOP, BOT_REL_POS_END };
@ -53,7 +56,7 @@ struct out_rect_data {
};
void reset_screen_info(ScreenInfo &info);
void load_screen_info(std::string key, std::string value, std::string base, ScreenInfo &info);
bool load_screen_info(std::string key, std::string value, std::string base, ScreenInfo &info);
std::string save_screen_info(std::string base, const ScreenInfo &info);
enum TextKind {TEXT_KIND_NORMAL, TEXT_KIND_SELECTED, TEXT_KIND_SUCCESS, TEXT_KIND_WARNING, TEXT_KIND_ERROR};

View File

@ -84,6 +84,7 @@ void WindowScreen::reload() {
}
void WindowScreen::poll() {
float old_scaling = 0.0;
this->poll_window();
while(!events_queue.empty()) {
SFEvent event_data = events_queue.front();
@ -124,6 +125,7 @@ void WindowScreen::poll() {
case 'b':
this->m_info.is_blurred = !this->m_info.is_blurred;
this->future_operations.call_blur = true;
this->print_notification_on_off("Blur", this->m_info.is_blurred);
break;
case 'v':
@ -137,15 +139,25 @@ void WindowScreen::poll() {
break;
case '-':
if(this->m_info.is_fullscreen)
break;
old_scaling = this->m_info.scaling;
this->m_info.scaling -= 0.5;
if (this->m_info.scaling < 1.25)
this->m_info.scaling = 1.0;
if(old_scaling != this->m_info.scaling)
this->print_notification("Scaling: " + std::to_string(this->m_info.scaling));
break;
case '0':
if(this->m_info.is_fullscreen)
break;
old_scaling = this->m_info.scaling;
this->m_info.scaling += 0.5;
if (this->m_info.scaling > 44.75)
this->m_info.scaling = 45.0;
if(old_scaling != this->m_info.scaling)
this->print_notification("Scaling: " + std::to_string(this->m_info.scaling));
break;
case 'o':
@ -237,21 +249,15 @@ void WindowScreen::poll() {
break;
case 'm':
audio_data->mute = !audio_data->mute;
audio_data->change_audio_mute();
break;
case ',':
audio_data->mute = false;
audio_data->volume -= 5;
if(audio_data->volume < 0)
audio_data->volume = 0;
audio_data->change_audio_volume(false);
break;
case '.':
audio_data->mute = false;
audio_data->volume += 5;
if(audio_data->volume > 100)
audio_data->volume = 100;
audio_data->change_audio_volume(true);
break;
default:

View File

@ -14,7 +14,8 @@ Sample::Sample(sf::Int16 *bytes, std::size_t size, float time) : bytes(bytes), s
//============================================================================
Audio::Audio() {
Audio::Audio(AudioData *audio_data) {
this->audio_data = audio_data;
sf::SoundStream::initialize(AUDIO_CHANNELS, SAMPLE_RATE);
#if (SFML_VERSION_MAJOR > 2) || ((SFML_VERSION_MAJOR == 2) && (SFML_VERSION_MINOR >= 6))
// Since we receive data every 16.6 ms, this is useless,
@ -22,30 +23,15 @@ Audio::Audio() {
//sf::SoundStream::setProcessingInterval(sf::Time::Zero);
#endif
start_audio();
setVolume(0);
this->final_volume = 0;
}
void Audio::update_volume(int volume, bool mute) {
if(mute && (mute == loaded_mute)) {
return;
}
if(volume < 0)
volume = 0;
if(volume > 100)
volume = 100;
if(mute != loaded_mute) {
loaded_mute = mute;
loaded_volume = volume;
}
else if(volume != loaded_volume) {
loaded_mute = mute;
loaded_volume = volume;
}
else {
return;
}
setVolume(mute ? 0 : volume);
void Audio::update_volume() {
int new_final_volume = this->audio_data->get_final_volume();
if(this->final_volume != new_final_volume)
setVolume(new_final_volume);
this->final_volume = new_final_volume;
}
void Audio::start_audio() {

78
source/audio_data.cpp Executable file
View File

@ -0,0 +1,78 @@
#include "audio_data.hpp"
void AudioData::reset() {
this->volume = 50;
this->mute = false;
this->text_updated = false;
}
void AudioData::change_audio_volume(bool is_change_positive) {
bool initial_audio_mute = this->mute;
int initial_audio_volume = this->volume;
int volume_change = 5;
if(!is_change_positive)
volume_change *= -1;
this->set_audio_volume(this->volume + volume_change);
this->set_audio_mute(false);
if((this->volume != initial_audio_volume) || (initial_audio_mute))
this->text_updated = true;
}
void AudioData::change_audio_mute() {
this->set_audio_mute(!this->mute);
this->text_updated = true;
}
bool AudioData::has_text_to_print() {
bool retval = this->text_updated;
this->text_updated = false;
return retval;
}
std::string AudioData::text_to_print() {
if(this->mute)
return "Audio muted";
return "Volume: " + std::to_string(this->get_final_volume()) + "%";
}
int AudioData::get_final_volume() {
if(this->mute)
return 0;
int read_volume = this->volume;
if(read_volume < 0)
read_volume = 0;
if(read_volume > 100)
read_volume = 100;
return read_volume;
}
bool AudioData::load_audio_data(std::string key, std::string value) {
if (key == this->mute_str) {
this->set_audio_mute(std::stoi(value));
return true;
}
if (key == this->volume_str) {
this->set_audio_volume(std::stoi(value));
return true;
}
return false;
}
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";
return out_str;
}
void AudioData::set_audio_volume(int new_volume) {
if(new_volume < 0)
new_volume = 0;
if(new_volume > 100)
new_volume = 100;
this->volume = new_volume;
}
void AudioData::set_audio_mute(bool new_mute) {
this->mute = new_mute;
}

View File

@ -39,7 +39,8 @@ struct OutTextData {
};
void ConsoleOutText(std::string full_text) {
std::cout << "[" << NAME << "] " << full_text << std::endl;
if(full_text != "")
std::cout << "[" << NAME << "] " << full_text << std::endl;
}
void UpdateOutText(OutTextData &out_text_data, std::string full_text, std::string small_text, TextKind kind) {
@ -81,31 +82,23 @@ bool load(const std::string path, const std::string name, ScreenInfo &top_info,
if (std::getline(kvp, value)) {
load_screen_info(key, value, "bot_", bottom_info);
load_screen_info(key, value, "joint_", joint_info);
load_screen_info(key, value, "top_", top_info);
if(bottom_info.crop_kind != Crop::NATIVE_DS)
bottom_info.crop_kind = Crop::DEFAULT_3DS;
if (key == "mute") {
audio_data->mute = std::stoi(value);
if(load_screen_info(key, value, "bot_", bottom_info)) {
if(bottom_info.crop_kind != Crop::NATIVE_DS)
bottom_info.crop_kind = Crop::DEFAULT_3DS;
continue;
}
if(load_screen_info(key, value, "joint_", joint_info))
continue;
if(load_screen_info(key, value, "top_", top_info))
continue;
if (key == "split") {
display_data.split = std::stoi(value);
continue;
}
if (key == "volume") {
int pre_loaded_volume = std::stoi(value);
if(pre_loaded_volume < 0)
pre_loaded_volume = 0;
if(pre_loaded_volume > 100)
pre_loaded_volume = 100;
audio_data->volume = pre_loaded_volume;
if(audio_data->load_audio_data(key, value))
continue;
}
}
}
}
@ -129,21 +122,18 @@ bool save(const std::string path, const std::string name, const ScreenInfo &top_
file << save_screen_info("bot_", bottom_info);
file << save_screen_info("joint_", joint_info);
file << save_screen_info("top_", top_info);
file << "mute=" << audio_data->mute << std::endl;
file << "split=" << display_data.split << std::endl;
file << "volume=" << audio_data->volume << std::endl;
file << audio_data->save_audio_data();
file.close();
return true;
}
void soundCall(AudioData *audio_data, CaptureData* capture_data) {
Audio audio;
Audio audio(audio_data);
sf::Int16 out_buf[NUM_CONCURRENT_AUDIO_BUFFERS][MAX_SAMPLES_IN];
int curr_out, prev_out = NUM_CONCURRENT_DATA_BUFFERS - 1, audio_buf_counter = 0;
const bool endianness = is_big_endian();
audio.update_volume(0, true);
volatile int loaded_samples;
while (capture_data->running) {
@ -176,14 +166,14 @@ void soundCall(AudioData *audio_data, CaptureData* capture_data) {
if(audio.restart) {
audio.stop();
audio.~Audio();
::new(&audio) Audio();
::new(&audio) Audio(audio_data);
}
audio.start_audio();
audio.play();
}
}
else {
audio.update_volume(audio_data->volume, audio_data->mute);
audio.update_volume();
}
}
else {
@ -340,6 +330,10 @@ void mainVideoOutputCall(AudioData* audio_data, CaptureData* capture_data) {
}
}
if(audio_data->has_text_to_print()) {
UpdateOutText(out_text_data, "", audio_data->text_to_print(), TEXT_KIND_NORMAL);
}
if(capture_data->new_error_text) {
UpdateOutText(out_text_data, capture_data->error_text, capture_data->error_text, TEXT_KIND_ERROR);
capture_data->new_error_text = false;
@ -381,9 +375,8 @@ int main(int argc, char **argv) {
XInitThreads();
#endif
AudioData audio_data;
audio_data.reset();
CaptureData* capture_data = new CaptureData;
audio_data.volume = 50;
audio_data.mute = false;
capture_data->connected = connect(true, capture_data);
std::thread capture_thread(captureCall, capture_data);

View File

@ -27,14 +27,14 @@ void reset_screen_info(ScreenInfo &info) {
info.bfi_divider = 2.0;
}
void load_screen_info(std::string key, std::string value, std::string base, ScreenInfo &info) {
bool load_screen_info(std::string key, std::string value, std::string base, ScreenInfo &info) {
if(key == (base + "blur")) {
info.is_blurred = std::stoi(value);
return;
return true;
}
if(key == (base + "crop")) {
info.crop_kind = static_cast<Crop>(std::stoi(value) % Crop::CROP_END);
return;
return true;
}
if(key == (base + "scale")) {
info.scaling = std::stod(value);
@ -42,70 +42,71 @@ void load_screen_info(std::string key, std::string value, std::string base, Scre
info.scaling = 1.0;
if(info.scaling > 44.75)
info.scaling = 45.0;
return;
return true;
}
if(key == (base + "fullscreen")) {
info.is_fullscreen = std::stoi(value);
return;
return true;
}
if(key == (base + "bot_pos")) {
info.bottom_pos = static_cast<BottomRelativePosition>(std::stoi(value) % BottomRelativePosition::BOT_REL_POS_END);
return;
return true;
}
if(key == (base + "sub_off_algo")) {
info.subscreen_offset_algorithm = static_cast<OffsetAlgorithm>(std::stoi(value) % OffsetAlgorithm::OFF_ALGO_END);
return;
return true;
}
if(key == (base + "sub_att_off_algo")) {
info.subscreen_attached_offset_algorithm = static_cast<OffsetAlgorithm>(std::stoi(value) % OffsetAlgorithm::OFF_ALGO_END);
return;
return true;
}
if(key == (base + "off_algo_x")) {
info.total_offset_algorithm_x = static_cast<OffsetAlgorithm>(std::stoi(value) % OffsetAlgorithm::OFF_ALGO_END);
return;
return true;
}
if(key == (base + "off_algo_y")) {
info.total_offset_algorithm_y = static_cast<OffsetAlgorithm>(std::stoi(value) % OffsetAlgorithm::OFF_ALGO_END);
return;
return true;
}
if(key == (base + "top_rot")) {
info.top_rotation = std::stoi(value);
info.top_rotation %= 360;
info.top_rotation += (info.top_rotation < 0) ? 360 : 0;
return;
return true;
}
if(key == (base + "bot_rot")) {
info.bot_rotation = std::stoi(value);
info.bot_rotation %= 360;
info.bot_rotation += (info.bot_rotation < 0) ? 360 : 0;
return;
return true;
}
if(key == (base + "vsync")) {
info.v_sync_enabled = std::stoi(value);
return;
return true;
}
if(key == (base + "async")) {
info.async = std::stoi(value);
return;
return true;
}
if(key == (base + "top_scaling")) {
info.top_scaling = std::stoi(value);
return;
return true;
}
if(key == (base + "bot_scaling")) {
info.bot_scaling = std::stoi(value);
return;
return true;
}
if(key == (base + "bfi")) {
info.bfi = std::stoi(value);
return;
return true;
}
if(key == (base + "bfi_divider")) {
info.bfi_divider = std::stod(value);
if(info.bfi_divider < 1.0)
info.bfi_divider = 1.0;
return;
return true;
}
return false;
}
std::string save_screen_info(std::string base, const ScreenInfo &info) {