diff --git a/desmume/src/frontend/posix/gtk/config_opts.h b/desmume/src/frontend/posix/gtk/config_opts.h
index b2536d6e8..6d2ac136f 100644
--- a/desmume/src/frontend/posix/gtk/config_opts.h
+++ b/desmume/src/frontend/posix/gtk/config_opts.h
@@ -67,4 +67,5 @@ OPT(multisampling, bool, false, Config, OpenGLMultisampling)
OPT(audio_enabled, bool, true, Audio, Enabled)
OPT(audio_sync, int, 0, Audio, Synchronization)
OPT(audio_interpolation, int, 1, Audio, Interpolation)
+OPT(audio_volume, int, 128, Audio, Volume)
diff --git a/desmume/src/frontend/posix/gtk/main.cpp b/desmume/src/frontend/posix/gtk/main.cpp
index bb5cd077d..9c81bb5ba 100644
--- a/desmume/src/frontend/posix/gtk/main.cpp
+++ b/desmume/src/frontend/posix/gtk/main.cpp
@@ -138,6 +138,7 @@ static void ResetSaveStateTimes();
static void LoadSaveStateInfo();
static void Printscreen();
static void Reset();
+static void SetAudioVolume();
static void Edit_Controls();
static void Edit_Joystick_Controls();
static void MenuSave(GtkMenuItem *item, gpointer slot);
@@ -358,6 +359,7 @@ static const char *ui_description =
" "
" "
" "
+" "
" "
" "
" "
@@ -436,6 +438,7 @@ static const GtkActionEntry action_entries[] = {
{ "cheatsearch", NULL, "_Search", NULL, NULL, CheatSearch },
{ "cheatlist", NULL, "_List", NULL, NULL, CheatList },
{ "ConfigSaveMenu", NULL, "_Saves" },
+ { "setaudiovolume", NULL, "Set audio _volume", NULL, NULL, SetAudioVolume },
{ "editctrls", NULL, "_Edit controls",NULL, NULL, Edit_Controls },
{ "editjoyctrls", NULL, "Edit _Joystick controls",NULL, NULL, Edit_Joystick_Controls },
@@ -1904,6 +1907,38 @@ static gint Key_Release(GtkWidget *w, GdkEventKey *e, gpointer data)
}
+/////////////////////////////// SET AUDIO VOLUME //////////////////////////////////////
+
+static void CallbackSetAudioVolume(GtkWidget* hscale, gpointer data)
+{
+ SNDSDLSetAudioVolume(gtk_range_get_value(GTK_RANGE(hscale)));
+ config.audio_volume = SNDSDLGetAudioVolume();
+}
+
+static void SetAudioVolume()
+{
+ GtkWidget *dialog = NULL;
+ GtkWidget *hscale = NULL;
+ int audio_volume = SNDSDLGetAudioVolume();
+ dialog = gtk_dialog_new_with_buttons("Set audio volume", GTK_WINDOW(pWindow), GTK_DIALOG_MODAL, GTK_STOCK_OK, GTK_RESPONSE_OK, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
+ hscale = gtk_hscale_new_with_range(0, SDL_MIX_MAXVOLUME, 1);
+ gtk_range_set_value(GTK_RANGE(hscale), SNDSDLGetAudioVolume());
+ g_signal_connect(G_OBJECT(hscale), "value-changed", G_CALLBACK(CallbackSetAudioVolume), NULL);
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hscale, TRUE, FALSE, 0);
+ gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
+ switch(gtk_dialog_run(GTK_DIALOG(dialog)))
+ {
+ case GTK_RESPONSE_OK:
+ break;
+ case GTK_RESPONSE_CANCEL:
+ case GTK_RESPONSE_NONE:
+ SNDSDLSetAudioVolume(audio_volume);
+ config.audio_volume = SNDSDLGetAudioVolume();
+ break;
+ }
+ gtk_widget_destroy(dialog);
+}
+
/////////////////////////////// CONTROLS EDIT //////////////////////////////////////
static void AcceptNewInputKey(GtkWidget *w, GdkEventKey *e, struct modify_key_ctx *ctx)
@@ -3453,6 +3488,8 @@ common_gtk_main( class configured_features *my_config)
g_timeout_add_seconds(my_config->timeout, timeout_exit_cb, GINT_TO_POINTER(my_config->timeout));
}
+ SNDSDLSetAudioVolume(config.audio_volume);
+
/* Video filter parameters */
video->SetFilterParameteri(VF_PARAM_SCANLINE_A, _scanline_filter_a);
video->SetFilterParameteri(VF_PARAM_SCANLINE_B, _scanline_filter_b);
diff --git a/desmume/src/frontend/posix/shared/sndsdl.cpp b/desmume/src/frontend/posix/shared/sndsdl.cpp
index e1a42b958..2012dc120 100644
--- a/desmume/src/frontend/posix/shared/sndsdl.cpp
+++ b/desmume/src/frontend/posix/shared/sndsdl.cpp
@@ -57,6 +57,7 @@ static volatile u32 soundpos;
static u32 soundlen;
static u32 soundbufsize;
static SDL_AudioSpec audiofmt;
+int audio_volume;
//////////////////////////////////////////////////////////////////////////////
#ifdef _XBOX
@@ -82,14 +83,17 @@ static void MixAudio(void *userdata, Uint8 *stream, int len) {
int i;
Uint8 *soundbuf=(Uint8 *)stereodata16;
+ Uint8 *stream_tmp=(Uint8 *)malloc(len);
for (i = 0; i < len; i++)
{
if (soundpos >= soundbufsize)
soundpos = 0;
- stream[i] = soundbuf[soundpos];
+ stream_tmp[i] = soundbuf[soundpos];
soundpos++;
}
+ SDL_MixAudio(stream, stream_tmp, len, audio_volume);
+ free(stream_tmp);
}
//////////////////////////////////////////////////////////////////////////////
@@ -222,3 +226,11 @@ void SNDSDLSetVolume(int volume)
}
//////////////////////////////////////////////////////////////////////////////
+int SNDSDLGetAudioVolume()
+{
+ return audio_volume;
+}
+void SNDSDLSetAudioVolume(int value)
+{
+ audio_volume = value;
+}
diff --git a/desmume/src/frontend/posix/shared/sndsdl.h b/desmume/src/frontend/posix/shared/sndsdl.h
index e003afd99..a4556981f 100644
--- a/desmume/src/frontend/posix/shared/sndsdl.h
+++ b/desmume/src/frontend/posix/shared/sndsdl.h
@@ -23,4 +23,7 @@
#define SNDCORE_SDL 2
extern SoundInterface_struct SNDSDL;
+extern int audio_volume;
+int SNDSDLGetAudioVolume();
+void SNDSDLSetAudioVolume(int value);
#endif