Browse Source

Support audio mix modes

Tiago Koji Castro Shibata 8 years ago
parent
commit
4c145e8c13

+ 4 - 0
platform/xcode/liblove.xcodeproj/project.pbxproj

@@ -7,6 +7,7 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
+		CEEB36EA1EE21DB90085BD77 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEEB36E91EE21DB90085BD77 /* AVFoundation.framework */; };
 		FA0B791B1A958E3B000E1D17 /* b64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B78F71A958E3B000E1D17 /* b64.cpp */; };
 		FA0B791C1A958E3B000E1D17 /* b64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B78F71A958E3B000E1D17 /* b64.cpp */; };
 		FA0B791D1A958E3B000E1D17 /* b64.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B78F81A958E3B000E1D17 /* b64.h */; };
@@ -918,6 +919,7 @@
 
 /* Begin PBXFileReference section */
 		503971A86B7167A91B670FBA /* boot.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = boot.lua.h; sourceTree = "<group>"; };
+		CEEB36E91EE21DB90085BD77 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
 		FA08F5AE16C7525600F007B5 /* liblove-macosx.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "liblove-macosx.plist"; path = "macosx/liblove-macosx.plist"; sourceTree = "<group>"; };
 		FA0B78DD1A958B90000E1D17 /* liblove.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = liblove.a; sourceTree = BUILT_PRODUCTS_DIR; };
 		FA0B78F71A958E3B000E1D17 /* b64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = b64.cpp; sourceTree = "<group>"; };
@@ -1597,6 +1599,7 @@
 			isa = PBXFrameworksBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				CEEB36EA1EE21DB90085BD77 /* AVFoundation.framework in Frameworks */,
 				FA27B3C91B498623008A9DCE /* Theora.framework in Frameworks */,
 				FA317EBA18F28B6D00B0BCD7 /* libz.dylib in Frameworks */,
 				FAA627CE18E7E1560080752D /* CoreServices.framework in Frameworks */,
@@ -2824,6 +2827,7 @@
 		FA577A6616C7199700860150 /* Frameworks */ = {
 			isa = PBXGroup;
 			children = (
+				CEEB36E91EE21DB90085BD77 /* AVFoundation.framework */,
 				FA0B7EEB1A959125000E1D17 /* macosx */,
 			);
 			name = Frameworks;

+ 10 - 0
src/common/ios.h

@@ -64,6 +64,16 @@ std::string getExecutablePath();
  **/
 void vibrate();
 
+/**
+ * Enable mix mode (e.g. with background music apps) and playback with a muted device.
+ **/
+void setAudioMixWithOthers(bool mixMode, bool playMuted);
+
+/**
+ * Returns whether another application is playing audio.
+ **/
+bool audioShouldBeSilenced();
+
 } // ios
 } // love
 

+ 34 - 0
src/common/ios.mm

@@ -26,6 +26,7 @@
 #import <UIKit/UIKit.h>
 
 #import <AudioToolbox/AudioServices.h>
+#import <AVFoundation/AVFoundation.h>
 
 #include <vector>
 
@@ -344,6 +345,39 @@ void vibrate()
 	}
 }
 
+void setAudioMixWithOthers(bool mixMode, bool playMuted)
+{
+	@autoreleasepool
+	{
+		NSError* err;
+		if (mixMode)
+		{
+			if (playMuted)
+			{
+				[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&err];
+			}
+			else
+			{
+				[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:&err];
+			}
+		}
+		else
+		{
+			if (playMuted)
+			{
+				[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&err];
+			}
+		}
+		if (err != nil)
+			NSLog(@"Error in AVAudioSession setCategory: %@", [err localizedDescription]);
+	}
+}
+
+bool audioShouldBeSilenced()
+{
+	return [[AVAudioSession sharedInstance] secondaryAudioShouldBeSilencedHint];
+}
+
 } // ios
 } // love
 

+ 12 - 0
src/modules/audio/wrap_Audio.cpp

@@ -25,6 +25,7 @@
 #include "null/Audio.h"
 
 #include "common/runtime.h"
+#include "common/ios.h"
 
 // C++
 #include <iostream>
@@ -293,6 +294,16 @@ int w_getDistanceModel(lua_State *L)
 	return 1;
 }
 
+int w_getShouldBeSilenced(lua_State *L)
+{
+#ifdef LOVE_IOS
+	lua_pushboolean(L, love::ios::audioShouldBeSilenced());
+#else
+	lua_pushboolean(L, 0);
+#endif
+	return 1;
+}
+
 // List of functions to wrap.
 static const luaL_Reg functions[] =
 {
@@ -318,6 +329,7 @@ static const luaL_Reg functions[] =
 	{ "stopRecording", w_stopRecording },*/
 	{ "setDistanceModel", w_setDistanceModel },
 	{ "getDistanceModel", w_getDistanceModel },
+	{ "getShouldBeSilenced", w_getShouldBeSilenced },
 	{ 0, 0 }
 };
 

+ 14 - 0
src/modules/love/love.cpp

@@ -23,6 +23,7 @@
 #include "common/version.h"
 #include "common/runtime.h"
 #include "common/wrap_Data.h"
+#include "common/ios.h"
 
 #include "love.h"
 
@@ -258,6 +259,14 @@ static int w__setGammaCorrect(lua_State *L)
 	return 0;
 }
 
+#ifdef LOVE_IOS
+static int w__setAudioMixMode(lua_State *L)
+{
+	love::ios::setAudioMixWithOthers(lua_toboolean(L, 1), lua_toboolean(L, 2));
+	return 0;
+}
+#endif
+
 int luaopen_love(lua_State *L)
 {
 	love::luax_insistpinnedthread(L);
@@ -291,6 +300,11 @@ int luaopen_love(lua_State *L)
 	lua_pushcfunction(L, w__setGammaCorrect);
 	lua_setfield(L, -2, "_setGammaCorrect");
 
+#ifdef LOVE_IOS
+	lua_pushcfunction(L, w__setAudioMixMode);
+	lua_setfield(L, -2, "_setAudioMixMode");
+#endif
+
 	lua_newtable(L);
 
 	for (int i = 0; love::VERSION_COMPATIBILITY[i] != nullptr; i++)

+ 8 - 0
src/scripts/boot.lua

@@ -373,6 +373,10 @@ function love.init()
 			window = true,
 			video = true,
 		},
+		audio = {
+			mixmode = true,
+			playmuted = false,
+		},
 		console = false, -- Only relevant for windows.
 		identity = false,
 		appendidentity = false,
@@ -416,6 +420,10 @@ function love.init()
 		love._setGammaCorrect(c.gammacorrect)
 	end
 
+	if love._setAudioMixMode then
+		love._setAudioMixMode(c.audio.mixmode, c.audio.playmuted)
+	end
+
 	-- Gets desired modules.
 	for k,v in ipairs{
 		"thread",

+ 12 - 0
src/scripts/boot.lua.h

@@ -682,6 +682,11 @@ const unsigned char boot_lua[] =
 	0x09, 0x09, 0x09, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a,
 	0x09, 0x09, 0x09, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a,
 	0x09, 0x09, 0x7d, 0x2c, 0x0a,
+	0x09, 0x09, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x20, 0x3d, 0x20, 0x7b, 0x0a,
+	0x09, 0x09, 0x09, 0x6d, 0x69, 0x78, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a,
+	0x09, 0x09, 0x09, 0x70, 0x6c, 0x61, 0x79, 0x6d, 0x75, 0x74, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 
+	0x73, 0x65, 0x2c, 0x0a,
+	0x09, 0x09, 0x7d, 0x2c, 0x0a,
 	0x09, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 
 	0x20, 0x2d, 0x2d, 0x20, 0x4f, 0x6e, 0x6c, 0x79, 0x20, 0x72, 0x65, 0x6c, 0x65, 0x76, 0x61, 0x6e, 0x74, 0x20, 
 	0x66, 0x6f, 0x72, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x2e, 0x0a,
@@ -776,6 +781,13 @@ const unsigned char boot_lua[] =
 	0x72, 0x72, 0x65, 0x63, 0x74, 0x28, 0x63, 0x2e, 0x67, 0x61, 0x6d, 0x6d, 0x61, 0x63, 0x6f, 0x72, 0x72, 0x65, 
 	0x63, 0x74, 0x29, 0x0a,
 	0x09, 0x65, 0x6e, 0x64, 0x0a,
+	0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x73, 0x65, 0x74, 0x41, 0x75, 0x64, 0x69, 0x6f, 
+	0x4d, 0x69, 0x78, 0x4d, 0x6f, 0x64, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
+	0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x73, 0x65, 0x74, 0x41, 0x75, 0x64, 0x69, 0x6f, 0x4d, 0x69, 
+	0x78, 0x4d, 0x6f, 0x64, 0x65, 0x28, 0x63, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x2e, 0x6d, 0x69, 0x78, 0x6d, 
+	0x6f, 0x64, 0x65, 0x2c, 0x20, 0x63, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x2e, 0x70, 0x6c, 0x61, 0x79, 0x6d, 
+	0x75, 0x74, 0x65, 0x64, 0x29, 0x0a,
+	0x09, 0x65, 0x6e, 0x64, 0x0a,
 	0x09, 0x2d, 0x2d, 0x20, 0x47, 0x65, 0x74, 0x73, 0x20, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x20, 0x6d, 
 	0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x2e, 0x0a,
 	0x09, 0x66, 0x6f, 0x72, 0x20, 0x6b, 0x2c, 0x76, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x70, 0x61, 0x69, 0x72, 0x73,