diff --git a/iNDS/AppDelegate.m b/iNDS/AppDelegate.m
index 396b15d8..813c300c 100644
--- a/iNDS/AppDelegate.m
+++ b/iNDS/AppDelegate.m
@@ -596,7 +596,9 @@ - (WCEasySettingsViewController *)getSettingsViewController
// Audio
WCEasySettingsSection *audioSection = [[WCEasySettingsSection alloc] initWithTitle:@"Audio" subTitle:@""];
- audioSection.items = @[[[WCEasySettingsSwitch alloc] initWithIdentifier:@"disableSound"
+ audioSection.items = @[[[WCEasySettingsSlider alloc] initWithIdentifier:@"outputVolume"
+ title:@"Output Volume"],
+ [[WCEasySettingsSwitch alloc] initWithIdentifier:@"disableSound"
title:@"Disable Sound"],
[[WCEasySettingsSwitch alloc] initWithIdentifier:@"allowExternalAudio"
title:@"Allow External Audio"],
diff --git a/iNDS/core/emu.cpp b/iNDS/core/emu.cpp
index b94087a8..7737d570 100644
--- a/iNDS/core/emu.cpp
+++ b/iNDS/core/emu.cpp
@@ -301,14 +301,20 @@ void EMU_enableSound(bool enabled)
/*
SPU seems to need to be kickstarted. If left disabled when initializing the ROM,
then we can't expect to magically enable it partway through. To solve this, we
- just let it run for a cycle if we disable sound.
+ just let it run for a cycle if we disable sound. We only kick the SPU when soundEnabled has changed, to prevent unnecessarily kickstarting the SPU.
More information see iNDS-Team/iNDS#35
*/
- if (!enabled) SPU_Emulate_user(true);
+ if(!enabled && soundEnabled != enabled) SPU_Emulate_user(true);
soundEnabled = enabled;
}
+void EMU_setAudioOutputVolume(double volume)
+{
+ int vol = volume * 100;
+ SPU_SetVolume(vol);
+}
+
void EMU_setFrameSkip(int skip)
{
if (skip == -1) {
diff --git a/iNDS/core/emu.h b/iNDS/core/emu.h
index 9ebffd0d..3b7a8ffa 100644
--- a/iNDS/core/emu.h
+++ b/iNDS/core/emu.h
@@ -37,6 +37,7 @@ bool EMU_doRomLoad(const char* path, const char* logical);
bool EMU_loadRom(const char* path);
void EMU_change3D(int type);
void EMU_changeSound(int type);
+void EMU_setAudioOutputVolume(double volume);
void EMU_enableSound(bool enable);
bool EMU_frameSkip(bool force);
void EMU_setFrameSkip(int skip);
diff --git a/iNDS/core/sndcoreaudio.mm b/iNDS/core/sndcoreaudio.mm
index 83c05375..be28328e 100755
--- a/iNDS/core/sndcoreaudio.mm
+++ b/iNDS/core/sndcoreaudio.mm
@@ -41,6 +41,7 @@
static bool audioQueueStarted = false;
static AudioQueueBufferRef aqBuffer[NUM_BUFFERS];
static AudioQueueRef audioQueue;
+static float volume = 1.0;
void SNDCoreAudioCallback(void *data, AudioQueueRef mQueue, AudioQueueBufferRef mBuffer) {
mBuffer->mAudioDataByteSize = sndBufferSize;
@@ -119,14 +120,11 @@ void SNDCoreAudioMuteAudio() {
}
void SNDCoreAudioUnMuteAudio() {
- AudioQueueSetParameter(audioQueue, kAudioQueueParam_Volume, 1.0);
+ AudioQueueSetParameter(audioQueue, kAudioQueueParam_Volume, volume);
}
void SNDCoreAudioSetVolume(int volume) {
- /*
- This function was not implemented, but if it was implemented,
- this is how to do it.
float scaled = volume / 100.0;
+ ::volume = scaled;
AudioQueueSetParameter(audioQueue, kAudioQueueParam_Volume, scaled);
- */
}
diff --git a/iNDS/iNDSEmulatorViewController.mm b/iNDS/iNDSEmulatorViewController.mm
index 17cedc16..322587f0 100644
--- a/iNDS/iNDSEmulatorViewController.mm
+++ b/iNDS/iNDSEmulatorViewController.mm
@@ -373,6 +373,10 @@ - (void)defaultsChanged:(NSNotification*)notification
// (Mute on && don't ignore it) or user has sound disabled
BOOL muteSound = [defaults boolForKey:@"disableSound"];
EMU_enableSound(!muteSound);
+
+ double outputVolume = [defaults doubleForKey:@"outputVolume"];
+ EMU_setAudioOutputVolume(outputVolume);
+
AVAudioSessionCategoryOptions opts = AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionAllowBluetoothA2DP;
if([defaults boolForKey:@"allowExternalAudio"]){
opts |= AVAudioSessionCategoryOptionMixWithOthers;
diff --git a/iNDS/settings/Defaults.plist b/iNDS/settings/Defaults.plist
index 166671a4..c7cba66a 100755
--- a/iNDS/settings/Defaults.plist
+++ b/iNDS/settings/Defaults.plist
@@ -16,6 +16,8 @@
frameSkip
-1
+ outputVolume
+ 1
disableSound
allowExternalAudio