FLTK: Add option to mute audio

Adds a mute-on-startup entry in settings, a --mute (-m) command line
parameter, 'm' hotkey to mute on the fly, and a corresponding menubar
entry.
This commit is contained in:
HWXLR8 2025-01-01 14:14:24 -05:00 committed by rdanbrook
parent 76c5d0cdb7
commit 5e065f55af
9 changed files with 73 additions and 12 deletions

View file

@ -86,7 +86,12 @@ void audio_cb_input(void *data, uint8_t *stream, int len) {
AudioManager::AudioManager(JGManager& jgm, SettingManager& setmgr)
: jgm(jgm), setmgr(setmgr) {
jgm.set_audio_cb(AudioManager::queue);
if (setmgr.get_setting("a_mute")->val) {
jgm.set_audio_cb(AudioManager::null_queue);
}
else {
jgm.set_audio_cb(AudioManager::queue);
}
// Initialize audio buffers
buf_in = new int16_t[BUFSIZE];
@ -215,6 +220,10 @@ void AudioManager::queue(size_t in_size) {
SDL_UnlockAudioDevice(dev);
}
void AudioManager::null_queue(size_t in_size) {
return;
}
void AudioManager::rehash() {
if (srcstate) {
srcstate = src_delete(srcstate);
@ -264,3 +273,7 @@ void AudioManager::unpause() {
}
}
}
void AudioManager::mute(bool m) {
jgm.set_audio_cb(m ? AudioManager::null_queue : AudioManager::queue);
}

View file

@ -14,9 +14,11 @@ public:
void set_speed(int speed);
void pause();
void unpause();
void mute(bool m);
inline int16_t dequeue();
static void queue(size_t in_size);
static void null_queue(size_t in_size);
void rehash();

View file

@ -73,6 +73,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace {
int paused{0};
int muted{0};
int speed{1};
int video_fullscreen{0};
int syncmode{0};
@ -130,6 +131,7 @@ Fl_Menu_Item menutable[] = {
{0}, // End File
{"&Emulator", FL_ALT + 'e', 0, 0, FL_SUBMENU},
{"Pause", 0, FltkUi::pause, 0, FL_MENU_DIVIDER|FL_MENU_INACTIVE},
{"Mute", 0, FltkUi::mute, 0, FL_MENU_DIVIDER|FL_MENU_INACTIVE},
{"Reset (Soft)", 0, FltkUi::reset, (void*)"0", FL_MENU_INACTIVE},
{"Reset (Hard)", 0, FltkUi::reset, (void*)"1", FL_MENU_DIVIDER|FL_MENU_INACTIVE},
{"Fullscreen", 0, FltkUi::fullscreen, 0, FL_MENU_DIVIDER|FL_MENU_INACTIVE},
@ -471,6 +473,23 @@ void FltkUi::pause(Fl_Widget *w, void *data) {
#endif
}
void FltkUi::mute(Fl_Widget *w, void *data) {
Fl_Menu_Item* m = nullptr;
m = w ? const_cast<Fl_Menu_Item*>(((Fl_Menu_Bar*)w)->mvalue()) :
get_menuitem(muted ? "Unmute" : "Mute");
if (muted) {
audiomgr-> mute(false);
}
else {
audiomgr-> mute(true);
}
muted ^= 1;
m->label(muted ? "Unmute" : "Mute");
}
void FltkUi::reset(Fl_Widget *w, void *data) {
jgm->reset(atoi((const char*)data));
}
@ -705,7 +724,7 @@ void FltkUi::nstwin_open() {
chtwin->populate();
// Settings Window
setwin = new NstSettingsWindow(500, 550, "Settings", *jgm, *setmgr, *inputmgr);
setwin = new NstSettingsWindow(500, 600, "Settings", *jgm, *setmgr, *inputmgr);
setwin->set_crt_active(setmgr->get_setting("v_postproc")->val == 3);
// Main Window
@ -820,6 +839,14 @@ int main(int argc, char *argv[]) {
setmgr->read(*jgm);
LogDriver::set_level(setmgr->get_setting("l_loglevel")->val);
// Change "Mute" menubar label based on whether audio is muted at
// startup
Fl_Menu_Item *m = get_menuitem("Mute");
if (setmgr->get_setting("a_mute")->val) {
m->label("Unmute");
muted = 1;
}
// Bring up Audio/Video managers
audiomgr = new AudioManager(*jgm, *setmgr);
videomgr = new VideoManager(*jgm, *setmgr);
@ -870,6 +897,11 @@ int main(int argc, char *argv[]) {
FltkUi::fullscreen(NULL, NULL);
}
if (std::find(flags.begin(), flags.end(), "-m") != flags.end() ||
std::find(flags.begin(), flags.end(), "--mute") != flags.end()) {
FltkUi::mute();
}
syncmode = setmgr->get_setting("m_syncmode")->val;
LogDriver::log(LogLevel::Debug, syncmode ?
"Synchronization Mode: VSync" :

View file

@ -58,6 +58,7 @@ public:
static void state_qload(Fl_Widget *w = nullptr, void *data = nullptr);
static void state_qsave(Fl_Widget *w = nullptr, void *data = nullptr);
static void pause(Fl_Widget *w = nullptr, void *data = nullptr);
static void mute(Fl_Widget *w = nullptr, void *data = nullptr);
static void reset(Fl_Widget *w = nullptr, void *data = nullptr);
static void palette_open(Fl_Widget *w = nullptr, void *data = nullptr);
static void setwin_open(Fl_Widget *w = nullptr, void *data = nullptr);

View file

@ -52,9 +52,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace {
constexpr int UI_TABHEIGHT = 500;
constexpr int UI_TABHEIGHT = 550;
constexpr int UI_TABWIDTH = 480;
constexpr unsigned UI_SETTINGS_PER_COL = 9;
constexpr unsigned UI_SETTINGS_PER_COL = 10;
std::unordered_map<int, std::string> keycodes = { //FL_Button ??
{ ' ', "Space" },

View file

@ -53,16 +53,16 @@ jg_inputinfo_t *inputinfo[5]{nullptr};
jg_inputstate_t uistate;
jg_inputinfo_t uiinfo;
constexpr size_t NDEFS_UI = 13;
constexpr size_t NDEFS_UI = 14;
const char *defs_ui[NDEFS_UI] = {
"ResetSoft", "ResetHard", "FDSNextSide", "FDSInsertEject",
"QuickSave1", "QuickSave2", "QuickLoad1", "QuickLoad2",
"Fullscreen", "Pause", "FastForward", "Screenshot", "Quit"
"Fullscreen", "Pause", "Mute", "FastForward", "Screenshot", "Quit"
};
const int ui_defaults[NDEFS_UI - 1] = {
0xffbd + 1, 0xffbd + 2, 0xffbd + 3, 0xffbd + 4, 0xffbd + 5,
0xffbd + 6, 0xffbd + 7, 0xffbd + 8, 'f', 'p', '`', 0xffbd + 9
0xffbd + 6, 0xffbd + 7, 0xffbd + 8, 'f', 'p', 'm', '`', 0xffbd + 9
};
bool uiprev[NDEFS_UI]{};
@ -493,7 +493,7 @@ void InputManager::event(SDL_Event& evt) {
if (jxmap[axis] != nullptr) {
*jxmap[axis] = abs(evt.jaxis.value) > DEADZONE ? evt.jaxis.value : 0;
}
break;
}
}
@ -553,13 +553,16 @@ void InputManager::ui_events() {
case 9: // Pause
UiAdapter::pause();
break;
case 10: // FastForward
case 10: // Mute
UiAdapter::mute();
break;
case 11: // FastForward
UiAdapter::fastforward(false);
break;
case 11: // Screenshot
case 12: // Screenshot
UiAdapter::screenshot();
break;
case 12: // Quit
case 13: // Quit
UiAdapter::quit();
break;
}
@ -568,7 +571,7 @@ void InputManager::ui_events() {
uiprev[i] = uistate.button[i];
}
if (uistate.button[10]) {
if (uistate.button[11]) {
UiAdapter::fastforward(true);
}
}

View file

@ -71,6 +71,11 @@ jg_setting_t fe_settings[] = {
"Set the window's initial scale factor (multiple of NES resolution)",
3, 1, 16, FLAG_FRONTEND | JG_SETTING_RESTART
},
{ "a_mute", "Start with Audio Muted",
"0 = Disabled, 1 = Enabled",
"Start the emulator with audio muted",
0, 0, 1, FLAG_FRONTEND
},
{ "a_rsqual", "Audio Resampler",
"0 = Sinc (Best), 1 = Sinc (Medium), 2 = Sinc (Fast), 3 = Zero Order Hold, 4 = Linear",
"Set the frontend's audio resampling quality. Use Sinc unless you are on extremely weak hardware.",

View file

@ -54,6 +54,10 @@ void UiAdapter::pause() {
FltkUi::pause();
}
void UiAdapter::mute() {
FltkUi::mute();
}
void UiAdapter::screenshot() {
FltkUi::screenshot();
}

View file

@ -8,6 +8,7 @@ public:
static void fullscreen();
static void fastforward(bool ff);
static void pause();
static void mute();
static void screenshot();
static void quit();
static void show_inputmsg(int show);