From 4c145e8c130c68662c6f35d55953e582dcf898c8 Mon Sep 17 00:00:00 2001 From: Tiago Koji Castro Shibata Date: Fri, 2 Jun 2017 19:35:58 -0300 Subject: [PATCH] Support audio mix modes --- .../xcode/liblove.xcodeproj/project.pbxproj | 4 +++ src/common/ios.h | 10 ++++++ src/common/ios.mm | 34 +++++++++++++++++++ src/modules/audio/wrap_Audio.cpp | 12 +++++++ src/modules/love/love.cpp | 14 ++++++++ src/scripts/boot.lua | 8 +++++ src/scripts/boot.lua.h | 12 +++++++ 7 files changed, 94 insertions(+) diff --git a/platform/xcode/liblove.xcodeproj/project.pbxproj b/platform/xcode/liblove.xcodeproj/project.pbxproj index d21bd683c..f958de2d3 100644 --- a/platform/xcode/liblove.xcodeproj/project.pbxproj +++ b/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 = ""; }; + 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 = ""; }; 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 = ""; }; @@ -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; diff --git a/src/common/ios.h b/src/common/ios.h index 43a4c7c7c..1b74a6a1e 100644 --- a/src/common/ios.h +++ b/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 diff --git a/src/common/ios.mm b/src/common/ios.mm index c17c17bde..70a7f35ce 100644 --- a/src/common/ios.mm +++ b/src/common/ios.mm @@ -26,6 +26,7 @@ #import #import +#import #include @@ -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 diff --git a/src/modules/audio/wrap_Audio.cpp b/src/modules/audio/wrap_Audio.cpp index 0e617ff76..956f8da23 100644 --- a/src/modules/audio/wrap_Audio.cpp +++ b/src/modules/audio/wrap_Audio.cpp @@ -25,6 +25,7 @@ #include "null/Audio.h" #include "common/runtime.h" +#include "common/ios.h" // C++ #include @@ -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 } }; diff --git a/src/modules/love/love.cpp b/src/modules/love/love.cpp index 64d3d4586..f56bd7eee 100644 --- a/src/modules/love/love.cpp +++ b/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++) diff --git a/src/scripts/boot.lua b/src/scripts/boot.lua index ed903a61a..418c557d3 100644 --- a/src/scripts/boot.lua +++ b/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", diff --git a/src/scripts/boot.lua.h b/src/scripts/boot.lua.h index 6d0fbadb7..e53ba39ab 100644 --- a/src/scripts/boot.lua.h +++ b/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,