Merged in AuahDark/love/androidmic (pull request #126)

Recording support for Android (C++ side)
This commit is contained in:
Alex Szpakowski
2019-09-29 12:30:13 +00:00
8 changed files with 183 additions and 8 deletions
+53
View File
@@ -266,6 +266,59 @@ bool hasBackgroundMusic()
return result;
}
bool hasRecordingPermission()
{
JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv();
jobject activity = (jobject) SDL_AndroidGetActivity();
jclass clazz(env->GetObjectClass(activity));
jmethodID methodID = env->GetMethodID(clazz, "hasRecordAudioPermission", "()Z");
jboolean result = false;
if (methodID == nullptr)
env->ExceptionClear();
else
result = env->CallBooleanMethod(activity, methodID);
env->DeleteLocalRef(activity);
env->DeleteLocalRef(clazz);
return result;
}
void requestRecordingPermission()
{
JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv();
jobject activity = (jobject) SDL_AndroidGetActivity();
jclass clazz(env->GetObjectClass(activity));
jmethodID methodID = env->GetMethodID(clazz, "requestRecordAudioPermission", "()V");
if (methodID == nullptr)
env->ExceptionClear();
else
env->CallVoidMethod(activity, methodID);
env->DeleteLocalRef(clazz);
env->DeleteLocalRef(activity);
}
void showRecordingPermissionMissingDialog()
{
JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv();
jobject activity = (jobject) SDL_AndroidGetActivity();
jclass clazz(env->GetObjectClass(activity));
jmethodID methodID = env->GetMethodID(clazz, "showRecordingAudioPermissionMissingDialog", "()V");
if (methodID == nullptr)
env->ExceptionClear();
else
env->CallVoidMethod(activity, methodID);
env->DeleteLocalRef(clazz);
env->DeleteLocalRef(activity);
}
} // android
} // love
+6
View File
@@ -74,6 +74,12 @@ bool createStorageDirectories();
bool hasBackgroundMusic();
bool hasRecordingPermission();
void requestRecordingPermission();
void showRecordingPermissionMissingDialog();
} // android
} // love
+39 -1
View File
@@ -21,8 +21,10 @@
#include "Audio.h"
#include "common/config.h"
#ifdef LOVE_IOS
#if defined(LOVE_IOS)
#include "common/ios.h"
#elif defined(LOVE_ANDROID)
#include "common/android.h"
#endif
namespace love
@@ -30,6 +32,42 @@ namespace love
namespace audio
{
static bool requestRecPermission = false;
void setRequestRecordingPermission(bool rec)
{
requestRecPermission = rec;
}
bool getRequestRecordingPermission()
{
return requestRecPermission;
}
bool hasRecordingPermission()
{
#if defined(LOVE_ANDROID)
return love::android::hasRecordingPermission();
#else
// Always available(?)
return true;
#endif
}
void requestRecordingPermission()
{
#ifdef LOVE_ANDROID
love::android::requestRecordingPermission();
#endif
}
void showRecordingPermissionMissingDialog()
{
#ifdef LOVE_ANDROID
love::android::showRecordingPermissionMissingDialog();
#endif
}
bool Audio::setMixWithSystem(bool mix)
{
#ifdef LOVE_IOS
+28
View File
@@ -45,6 +45,34 @@ class SoundData;
namespace audio
{
/*
* In some platforms (notably Android), recording from mic
* requires user permission. This function sets whetever to
* request the permission later or not.
*/
void setRequestRecordingPermission(bool rec);
/*
* Gets whetever recording permission will be requested.
*/
bool getRequestRecordingPermission();
/*
* Gets whetever recording permission is granted.
*/
bool hasRecordingPermission();
/*
* Request recording permission. This is blocking function.
*/
void requestRecordingPermission();
/*
* In case recording permission is not granted, this
* function shows the dialog about the recording permission.
*/
void showRecordingPermissionMissingDialog();
/**
* The Audio module is responsible for playing back raw sound samples.
**/
+18
View File
@@ -101,6 +101,15 @@ Audio::Audio()
love::thread::disableSignals();
#endif
// Before opening new device, check if recording
// is requested.
if (getRequestRecordingPermission())
{
if (!hasRecordingPermission())
// Request recording permission on some OSes.
requestRecordingPermission();
}
// Passing null for default device.
device = alcOpenDevice(nullptr);
@@ -402,6 +411,15 @@ const std::vector<love::audio::RecordingDevice*> &Audio::getRecordingDevices()
std::vector<std::string> devnames;
std::vector<love::audio::RecordingDevice*> devices;
// If recording permission is not granted, inform user about it
// and return empty list.
if (!hasRecordingPermission() && getRequestRecordingPermission())
{
showRecordingPermissionMissingDialog();
capture.clear();
return capture;
}
std::string defaultname(alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
//no device name obtained from AL, fallback to reading from device
+10
View File
@@ -335,6 +335,14 @@ static int w__setAudioMixWithSystem(lua_State *L)
return 1;
}
static int w__requestRecordingPermission(lua_State *L)
{
#ifdef LOVE_ENABLE_AUDIO
love::audio::setRequestRecordingPermission((bool) lua_toboolean(L, 1));
#endif
return 0;
}
static int w_love_setDeprecationOutput(lua_State *L)
{
bool enable = love::luax_checkboolean(L, 1);
@@ -396,6 +404,8 @@ int luaopen_love(lua_State *L)
// module is initialized.
lua_pushcfunction(L, w__setAudioMixWithSystem);
lua_setfield(L, -2, "_setAudioMixWithSystem");
lua_pushcfunction(L, w__requestRecordingPermission);
lua_setfield(L, -2, "_requestRecordingPermission");
lua_newtable(L);
+9 -2
View File
@@ -425,6 +425,7 @@ function love.init()
},
audio = {
mixwithsystem = true, -- Only relevant for Android / iOS.
mic = false, -- Only relevant for Android.
},
console = false, -- Only relevant for windows.
identity = false,
@@ -469,8 +470,14 @@ function love.init()
love._setGammaCorrect(c.gammacorrect)
end
if love._setAudioMixWithSystem and c.audio then
love._setAudioMixWithSystem(c.audio.mixwithsystem)
if love._setAudioMixWithSystem then
if c.audio and c.audio.mixwithsystem ~= nil then
love._setAudioMixWithSystem(c.audio.mixwithsystem)
end
end
if love._requestRecordingPermission then
love._requestRecordingPermission(c.audio and c.audio.mic)
end
-- Gets desired modules.
+20 -5
View File
@@ -841,6 +841,9 @@ const unsigned char boot_lua[] =
0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x20, 0x2d, 0x2d, 0x20, 0x4f, 0x6e, 0x6c, 0x79, 0x20, 0x72, 0x65, 0x6c,
0x65, 0x76, 0x61, 0x6e, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x20,
0x2f, 0x20, 0x69, 0x4f, 0x53, 0x2e, 0x0a,
0x09, 0x09, 0x09, 0x6d, 0x69, 0x63, 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, 0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0x2e, 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,
@@ -944,11 +947,23 @@ const unsigned char boot_lua[] =
0x09, 0x65, 0x6e, 0x64, 0x0a,
0x0a,
0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x73, 0x65, 0x74, 0x41, 0x75, 0x64, 0x69, 0x6f,
0x4d, 0x69, 0x78, 0x57, 0x69, 0x74, 0x68, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x61, 0x6e, 0x64, 0x20,
0x63, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 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, 0x57, 0x69, 0x74, 0x68, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x28, 0x63, 0x2e, 0x61, 0x75, 0x64, 0x69,
0x6f, 0x2e, 0x6d, 0x69, 0x78, 0x77, 0x69, 0x74, 0x68, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x29, 0x0a,
0x4d, 0x69, 0x78, 0x57, 0x69, 0x74, 0x68, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
0x09, 0x09, 0x69, 0x66, 0x20, 0x63, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63,
0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x2e, 0x6d, 0x69, 0x78, 0x77, 0x69, 0x74, 0x68, 0x73, 0x79, 0x73, 0x74,
0x65, 0x6d, 0x20, 0x7e, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x73, 0x65, 0x74, 0x41, 0x75, 0x64, 0x69, 0x6f, 0x4d,
0x69, 0x78, 0x57, 0x69, 0x74, 0x68, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x28, 0x63, 0x2e, 0x61, 0x75, 0x64,
0x69, 0x6f, 0x2e, 0x6d, 0x69, 0x78, 0x77, 0x69, 0x74, 0x68, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x29, 0x0a,
0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x65, 0x6e, 0x64, 0x0a,
0x0a,
0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52,
0x65, 0x63, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e,
0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x65, 0x63,
0x6f, 0x72, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x28, 0x63,
0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x6f,
0x2e, 0x6d, 0x69, 0x63, 0x29, 0x0a,
0x09, 0x65, 0x6e, 0x64, 0x0a,
0x0a,
0x09, 0x2d, 0x2d, 0x20, 0x47, 0x65, 0x74, 0x73, 0x20, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x20, 0x6d,