mirror of https://github.com/axmolengine/axmol.git
* fixed #17685: [android] Audio in game couldn't be mute while a ring or a call is coming * Updates comments in AudioEngine-inl.cpp and removes extra empty line in javaactivity-android.cpp * Puts audio focus relative code to another java file named Cocos2dxAudioFocusManager.java Renames setAudioFocusLost to setAudioFocus. * Renames JNI function. * Register audio focus in onResume and unregister it in onPause.
This commit is contained in:
parent
270bcb28a5
commit
57170200dd
|
@ -23,8 +23,6 @@
|
|||
****************************************************************************/
|
||||
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
|
||||
|
||||
#define LOG_TAG "cocos2d-x debug info"
|
||||
|
||||
#include "audio/android/AudioEngine-inl.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
@ -43,6 +41,7 @@
|
|||
#include "base/CCEventDispatcher.h"
|
||||
#include "base/CCEventType.h"
|
||||
#include "base/CCEventListenerCustom.h"
|
||||
#include "base/ccUTF8.h"
|
||||
#include "platform/android/CCFileUtils-android.h"
|
||||
#include "platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxHelper.h"
|
||||
|
||||
|
@ -55,8 +54,14 @@
|
|||
using namespace cocos2d;
|
||||
using namespace cocos2d::experimental;
|
||||
|
||||
#define DELAY_TIME_TO_REMOVE 0.5f
|
||||
// Audio focus values synchronized with which in cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxActivity.java
|
||||
static const int AUDIOFOCUS_GAIN = 0;
|
||||
static const int AUDIOFOCUS_LOST = 1;
|
||||
static const int AUDIOFOCUS_LOST_TRANSIENT = 2;
|
||||
static const int AUDIOFOCUS_LOST_TRANSIENT_CAN_DUCK = 3;
|
||||
|
||||
static int __currentAudioFocus = AUDIOFOCUS_GAIN;
|
||||
static AudioEngineImpl* __impl = nullptr;
|
||||
|
||||
class CallerThreadUtils : public ICallerThreadUtils
|
||||
{
|
||||
|
@ -117,6 +122,7 @@ AudioEngineImpl::AudioEngineImpl()
|
|||
, _lazyInitLoop(true)
|
||||
{
|
||||
__callerThreadUtils.setCallerThreadId(std::this_thread::get_id());
|
||||
__impl = this;
|
||||
}
|
||||
|
||||
AudioEngineImpl::~AudioEngineImpl()
|
||||
|
@ -145,6 +151,8 @@ AudioEngineImpl::~AudioEngineImpl()
|
|||
{
|
||||
Director::getInstance()->getEventDispatcher()->removeEventListener(_onResumeListener);
|
||||
}
|
||||
|
||||
__impl = nullptr;
|
||||
}
|
||||
|
||||
bool AudioEngineImpl::init()
|
||||
|
@ -225,6 +233,14 @@ void AudioEngineImpl::onEnterForeground(EventCustom* event)
|
|||
_urlAudioPlayersNeedResume.clear();
|
||||
}
|
||||
|
||||
void AudioEngineImpl::setAudioFocusForAllPlayers(bool isFocus)
|
||||
{
|
||||
for (const auto& e : _audioPlayers)
|
||||
{
|
||||
e.second->setAudioFocus(isFocus);
|
||||
}
|
||||
}
|
||||
|
||||
int AudioEngineImpl::play2d(const std::string &filePath ,bool loop ,float volume)
|
||||
{
|
||||
ALOGV("play2d, _audioPlayers.size=%d", (int)_audioPlayers.size());
|
||||
|
@ -274,6 +290,7 @@ int AudioEngineImpl::play2d(const std::string &filePath ,bool loop ,float volume
|
|||
|
||||
player->setLoop(loop);
|
||||
player->setVolume(volume);
|
||||
player->setAudioFocus(__currentAudioFocus == AUDIOFOCUS_GAIN);
|
||||
player->play();
|
||||
}
|
||||
else
|
||||
|
@ -439,4 +456,31 @@ void AudioEngineImpl::uncacheAll()
|
|||
}
|
||||
}
|
||||
|
||||
// It's invoked from javaactivity-android.cpp
|
||||
void cocos_audioengine_focus_change(int focusChange)
|
||||
{
|
||||
if (focusChange < AUDIOFOCUS_GAIN || focusChange > AUDIOFOCUS_LOST_TRANSIENT_CAN_DUCK)
|
||||
{
|
||||
CCLOGERROR("cocos_audioengine_focus_change: unknown value: %d", focusChange);
|
||||
return;
|
||||
}
|
||||
CCLOG("cocos_audioengine_focus_change: %d", focusChange);
|
||||
__currentAudioFocus = focusChange;
|
||||
|
||||
if (__impl == nullptr)
|
||||
{
|
||||
CCLOGWARN("cocos_audioengine_focus_change: AudioEngineImpl isn't ready!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (__currentAudioFocus == AUDIOFOCUS_GAIN)
|
||||
{
|
||||
__impl->setAudioFocusForAllPlayers(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
__impl->setAudioFocusForAllPlayers(false);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -72,6 +72,7 @@ public:
|
|||
void uncacheAll();
|
||||
void preload(const std::string& filePath, const std::function<void(bool)>& callback);
|
||||
|
||||
void setAudioFocusForAllPlayers(bool isFocus);
|
||||
private:
|
||||
|
||||
void onEnterBackground(EventCustom* event);
|
||||
|
|
|
@ -68,6 +68,8 @@ public:
|
|||
|
||||
virtual float getVolume() const = 0;
|
||||
|
||||
virtual void setAudioFocus(bool isFocus) = 0;
|
||||
|
||||
virtual void setLoop(bool isLoop) = 0;
|
||||
|
||||
virtual bool isLoop() const = 0;
|
||||
|
|
|
@ -110,6 +110,11 @@ float PcmAudioPlayer::getVolume() const
|
|||
return _track->getVolume();
|
||||
}
|
||||
|
||||
void PcmAudioPlayer::setAudioFocus(bool isFocus)
|
||||
{
|
||||
_track->setAudioFocus(isFocus);
|
||||
}
|
||||
|
||||
void PcmAudioPlayer::setLoop(bool isLoop)
|
||||
{
|
||||
_track->setLoop(isLoop);
|
||||
|
|
|
@ -62,6 +62,8 @@ public:
|
|||
|
||||
virtual float getVolume() const override;
|
||||
|
||||
virtual void setAudioFocus(bool isFocus) override;
|
||||
|
||||
virtual void setLoop(bool isLoop) override;
|
||||
|
||||
virtual bool isLoop() const override;
|
||||
|
|
|
@ -41,6 +41,7 @@ Track::Track(const PcmData &pcmData)
|
|||
, _isVolumeDirty(true)
|
||||
, _isLoop(false)
|
||||
, _isInitialized(false)
|
||||
, _isAudioFocus(true)
|
||||
{
|
||||
init(_pcmData.pcmBuffer->data(), _pcmData.numFrames, _pcmData.bitsPerSample / 8 * _pcmData.numChannels);
|
||||
}
|
||||
|
@ -52,7 +53,8 @@ Track::~Track()
|
|||
|
||||
gain_minifloat_packed_t Track::getVolumeLR()
|
||||
{
|
||||
gain_minifloat_t v = gain_from_float(_volume);
|
||||
float volume = _isAudioFocus ? _volume : 0.0f;
|
||||
gain_minifloat_t v = gain_from_float(volume);
|
||||
return gain_minifloat_pack(v, v);
|
||||
}
|
||||
|
||||
|
@ -83,6 +85,12 @@ float Track::getVolume() const
|
|||
return _volume;
|
||||
}
|
||||
|
||||
void Track::setAudioFocus(bool isFocus)
|
||||
{
|
||||
_isAudioFocus = isFocus;
|
||||
setVolumeDirty(true);
|
||||
}
|
||||
|
||||
void Track::setState(State state)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(_stateMutex);
|
||||
|
|
|
@ -62,6 +62,8 @@ public:
|
|||
void setVolume(float volume);
|
||||
float getVolume() const;
|
||||
|
||||
void setAudioFocus(bool isFocus);
|
||||
|
||||
bool setPosition(float pos);
|
||||
float getPosition() const;
|
||||
|
||||
|
@ -96,6 +98,7 @@ private:
|
|||
std::mutex _volumeDirtyMutex;
|
||||
bool _isLoop;
|
||||
bool _isInitialized;
|
||||
bool _isAudioFocus;
|
||||
|
||||
friend class AudioMixerController;
|
||||
};
|
||||
|
|
|
@ -60,7 +60,7 @@ UrlAudioPlayer::UrlAudioPlayer(SLEngineItf engineItf, SLObjectItf outputMixObjec
|
|||
: _engineItf(engineItf), _outputMixObj(outputMixObject),
|
||||
_callerThreadUtils(callerThreadUtils), _id(-1), _assetFd(nullptr),
|
||||
_playObj(nullptr), _playItf(nullptr), _seekItf(nullptr), _volumeItf(nullptr),
|
||||
_volume(0.0f), _duration(0.0f), _isLoop(false), _state(State::INVALID),
|
||||
_volume(0.0f), _duration(0.0f), _isLoop(false), _isAudioFocus(true), _state(State::INVALID),
|
||||
_playEventCallback(nullptr), _isDestroyed(std::make_shared<bool>(false))
|
||||
{
|
||||
std::call_once(__onceFlag, [](){
|
||||
|
@ -215,16 +215,36 @@ void UrlAudioPlayer::play()
|
|||
}
|
||||
}
|
||||
|
||||
void UrlAudioPlayer::setVolume(float volume)
|
||||
void UrlAudioPlayer::setVolumeToSLPlayer(float volume)
|
||||
{
|
||||
_volume = volume;
|
||||
int dbVolume = 2000 * log10(volume);
|
||||
if (dbVolume < SL_MILLIBEL_MIN)
|
||||
{
|
||||
dbVolume = SL_MILLIBEL_MIN;
|
||||
}
|
||||
SLresult r = (*_volumeItf)->SetVolumeLevel(_volumeItf, dbVolume);
|
||||
SL_RETURN_IF_FAILED(r, "UrlAudioPlayer::setVolume %d failed", dbVolume);
|
||||
SL_RETURN_IF_FAILED(r, "UrlAudioPlayer::setVolumeToSLPlayer %d failed", dbVolume);
|
||||
}
|
||||
|
||||
void UrlAudioPlayer::setVolume(float volume)
|
||||
{
|
||||
_volume = volume;
|
||||
if (_isAudioFocus)
|
||||
{
|
||||
setVolumeToSLPlayer(_volume);
|
||||
}
|
||||
}
|
||||
|
||||
float UrlAudioPlayer::getVolume() const
|
||||
{
|
||||
return _volume;
|
||||
}
|
||||
|
||||
void UrlAudioPlayer::setAudioFocus(bool isFocus)
|
||||
{
|
||||
_isAudioFocus = isFocus;
|
||||
float volume = _isAudioFocus ? _volume : 0.0f;
|
||||
setVolumeToSLPlayer(volume);
|
||||
}
|
||||
|
||||
float UrlAudioPlayer::getDuration() const
|
||||
|
@ -362,11 +382,6 @@ void UrlAudioPlayer::rewind()
|
|||
// Not supported currently. since cocos audio engine will new -> prepare -> play again.
|
||||
}
|
||||
|
||||
float UrlAudioPlayer::getVolume() const
|
||||
{
|
||||
return _volume;
|
||||
}
|
||||
|
||||
void UrlAudioPlayer::setLoop(bool isLoop)
|
||||
{
|
||||
_isLoop = isLoop;
|
||||
|
|
|
@ -68,6 +68,8 @@ public:
|
|||
|
||||
virtual float getVolume() const override;
|
||||
|
||||
virtual void setAudioFocus(bool isFocus) override;
|
||||
|
||||
virtual void setLoop(bool isLoop) override;
|
||||
|
||||
virtual bool isLoop() const override;
|
||||
|
@ -97,6 +99,8 @@ private:
|
|||
|
||||
void playEventCallback(SLPlayItf caller, SLuint32 playEvent);
|
||||
|
||||
void setVolumeToSLPlayer(float volume);
|
||||
|
||||
private:
|
||||
SLEngineItf _engineItf;
|
||||
SLObjectItf _outputMixObj;
|
||||
|
@ -115,6 +119,7 @@ private:
|
|||
float _volume;
|
||||
float _duration;
|
||||
bool _isLoop;
|
||||
bool _isAudioFocus;
|
||||
State _state;
|
||||
|
||||
PlayEventCallback _playEventCallback;
|
||||
|
|
|
@ -33,16 +33,13 @@ import android.media.AudioManager;
|
|||
import android.opengl.GLSurfaceView;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.preference.PreferenceManager.OnActivityResultListener;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import org.cocos2dx.lib.Cocos2dxHelper.Cocos2dxHelperListener;
|
||||
|
||||
|
@ -74,7 +71,7 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe
|
|||
public Cocos2dxGLSurfaceView getGLSurfaceView(){
|
||||
return mGLSurfaceView;
|
||||
}
|
||||
|
||||
|
||||
public static Context getContext() {
|
||||
return sContext;
|
||||
}
|
||||
|
@ -135,12 +132,13 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe
|
|||
Window window = this.getWindow();
|
||||
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
|
||||
|
||||
// Audio configuration
|
||||
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
||||
}
|
||||
|
||||
//native method,call GLViewImpl::getGLContextAttrs() to get the OpenGL ES context attributions
|
||||
private static native int[] getGLContextAttrs();
|
||||
|
||||
|
||||
// ===========================================================
|
||||
// Getter & Setter
|
||||
// ===========================================================
|
||||
|
@ -153,6 +151,7 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe
|
|||
protected void onResume() {
|
||||
Log.d(TAG, "onResume()");
|
||||
super.onResume();
|
||||
Cocos2dxAudioFocusManager.registerAudioFocusListener(this);
|
||||
this.hideVirtualButton();
|
||||
resumeIfHasFocus();
|
||||
}
|
||||
|
@ -178,12 +177,14 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe
|
|||
protected void onPause() {
|
||||
Log.d(TAG, "onPause()");
|
||||
super.onPause();
|
||||
Cocos2dxAudioFocusManager.unregisterAudioFocusListener(this);
|
||||
Cocos2dxHelper.onPause();
|
||||
mGLSurfaceView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
Cocos2dxAudioFocusManager.unregisterAudioFocusListener(this);
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
/****************************************************************************
|
||||
* Copyright (c) 2017 Chukong Technologies Inc.
|
||||
*
|
||||
* http://www.cocos2d-x.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
package org.cocos2dx.lib;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.AudioManager;
|
||||
import android.util.Log;
|
||||
|
||||
class Cocos2dxAudioFocusManager {
|
||||
|
||||
private final static String TAG = "AudioFocusManager";
|
||||
// Audio focus values synchronized with which in cocos/platform/android/javaactivity-android.cpp
|
||||
private final static int AUDIOFOCUS_GAIN = 0;
|
||||
private final static int AUDIOFOCUS_LOST = 1;
|
||||
private final static int AUDIOFOCUS_LOST_TRANSIENT = 2;
|
||||
private final static int AUDIOFOCUS_LOST_TRANSIENT_CAN_DUCK = 3;
|
||||
|
||||
private static AudioManager.OnAudioFocusChangeListener sAfChangeListener =
|
||||
new AudioManager.OnAudioFocusChangeListener() {
|
||||
public void onAudioFocusChange(int focusChange) {
|
||||
|
||||
Log.d(TAG, "onAudioFocusChange: " + focusChange + ", thread: " + Thread.currentThread().getName());
|
||||
|
||||
if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
|
||||
// Permanent loss of audio focus
|
||||
// Pause playback immediately
|
||||
Log.d(TAG, "Pause music by AUDIOFOCUS_LOSS");
|
||||
Cocos2dxHelper.runOnGLThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
nativeOnAudioFocusChange(AUDIOFOCUS_LOST);
|
||||
Cocos2dxHelper.setAudioFocus(false);
|
||||
}
|
||||
});
|
||||
|
||||
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
|
||||
// Pause playback
|
||||
Log.d(TAG, "Pause music by AUDIOFOCUS_LOSS_TRANSILENT");
|
||||
Cocos2dxHelper.runOnGLThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
nativeOnAudioFocusChange(AUDIOFOCUS_LOST_TRANSIENT);
|
||||
Cocos2dxHelper.setAudioFocus(false);
|
||||
}
|
||||
});
|
||||
} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
|
||||
// Lower the volume, keep playing
|
||||
Log.d(TAG, "Lower the volume, keep playing by AUDIOFOCUS_LOSS_TRANSILENT_CAN_DUCK");
|
||||
Cocos2dxHelper.runOnGLThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
nativeOnAudioFocusChange(AUDIOFOCUS_LOST_TRANSIENT_CAN_DUCK);
|
||||
Cocos2dxHelper.setAudioFocus(false);
|
||||
}
|
||||
});
|
||||
} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
|
||||
// Your app has been granted audio focus again
|
||||
// Raise volume to normal, restart playback if necessary
|
||||
Log.d(TAG, "Resume music by AUDIOFOCUS_GAIN");
|
||||
Cocos2dxHelper.runOnGLThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
nativeOnAudioFocusChange(AUDIOFOCUS_GAIN);
|
||||
Cocos2dxHelper.setAudioFocus(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static boolean registerAudioFocusListener(Context context) {
|
||||
AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
|
||||
// Request audio focus for playback
|
||||
int result = am.requestAudioFocus(sAfChangeListener,
|
||||
// Use the music stream.
|
||||
AudioManager.STREAM_MUSIC,
|
||||
// Request permanent focus.
|
||||
AudioManager.AUDIOFOCUS_GAIN);
|
||||
|
||||
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
|
||||
Log.d(TAG, "requestAudioFocus succeed");
|
||||
return true;
|
||||
}
|
||||
|
||||
Log.e(TAG, "requestAudioFocus failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
static void unregisterAudioFocusListener(Context context) {
|
||||
AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
int result = am.abandonAudioFocus(sAfChangeListener);
|
||||
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
|
||||
Log.d(TAG, "abandonAudioFocus succeed!");
|
||||
} else {
|
||||
Log.e(TAG, "abandonAudioFocus failed!");
|
||||
}
|
||||
|
||||
Cocos2dxHelper.runOnGLThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Cocos2dxHelper.setAudioFocus(true);
|
||||
nativeOnAudioFocusChange(AUDIOFOCUS_GAIN);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static native void nativeOnAudioFocusChange(int focusChange);
|
||||
}
|
|
@ -47,7 +47,6 @@ import android.util.DisplayMetrics;
|
|||
import android.util.Log;
|
||||
import android.view.Display;
|
||||
import android.view.WindowManager;
|
||||
import android.hardware.SensorManager;
|
||||
|
||||
import com.android.vending.expansion.zipfile.APKExpansionSupport;
|
||||
import com.android.vending.expansion.zipfile.ZipResourceFile;
|
||||
|
@ -438,6 +437,11 @@ public class Cocos2dxHelper {
|
|||
Cocos2dxHelper.sCocos2dSound.stopAllEffects();
|
||||
}
|
||||
|
||||
static void setAudioFocus(boolean isAudioFocus) {
|
||||
sCocos2dMusic.setAudioFocus(isAudioFocus);
|
||||
sCocos2dSound.setAudioFocus(isAudioFocus);
|
||||
}
|
||||
|
||||
public static void end() {
|
||||
Cocos2dxHelper.sCocos2dMusic.end();
|
||||
Cocos2dxHelper.sCocos2dSound.end();
|
||||
|
|
|
@ -51,6 +51,7 @@ public class Cocos2dxMusic {
|
|||
private boolean mPaused; // whether music is paused state.
|
||||
private boolean mIsLoop = false;
|
||||
private boolean mManualPaused = false; // whether music is paused manually before the program is switched to the background.
|
||||
private boolean mIsAudioFocus = true;
|
||||
private String mCurrentPath;
|
||||
|
||||
// ===========================================================
|
||||
|
@ -226,7 +227,7 @@ public class Cocos2dxMusic {
|
|||
}
|
||||
|
||||
this.mLeftVolume = this.mRightVolume = volume;
|
||||
if (this.mBackgroundMediaPlayer != null) {
|
||||
if (this.mBackgroundMediaPlayer != null && mIsAudioFocus) {
|
||||
this.mBackgroundMediaPlayer.setVolume(this.mLeftVolume, this.mRightVolume);
|
||||
}
|
||||
}
|
||||
|
@ -298,6 +299,16 @@ public class Cocos2dxMusic {
|
|||
return mediaPlayer;
|
||||
}
|
||||
|
||||
void setAudioFocus(boolean isFocus) {
|
||||
mIsAudioFocus = isFocus;
|
||||
|
||||
if (mBackgroundMediaPlayer != null) {
|
||||
float lVolume = mIsAudioFocus ? mLeftVolume : 0.0f;
|
||||
float rVolume = mIsAudioFocus ? mRightVolume : 0.0f;
|
||||
mBackgroundMediaPlayer.setVolume(lVolume, rVolume);
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================
|
||||
// Inner and Anonymous Classes
|
||||
// ===========================================================
|
||||
|
|
|
@ -52,6 +52,7 @@ public class Cocos2dxSound {
|
|||
private SoundPool mSoundPool;
|
||||
private float mLeftVolume;
|
||||
private float mRightVolume;
|
||||
private boolean mIsAudioFocus = true;
|
||||
|
||||
// sound path and stream ids map
|
||||
// a file may be played many times at the same time
|
||||
|
@ -255,6 +256,13 @@ public class Cocos2dxSound {
|
|||
|
||||
this.mLeftVolume = this.mRightVolume = volume;
|
||||
|
||||
if (!mIsAudioFocus)
|
||||
return;
|
||||
|
||||
setEffectsVolumeInternal(mLeftVolume, mRightVolume);
|
||||
}
|
||||
|
||||
private void setEffectsVolumeInternal(float left, float right) {
|
||||
synchronized (mLockPathStreamIDsMap) {
|
||||
// change the volume of playing sounds
|
||||
if (!this.mPathStreamIDsMap.isEmpty()) {
|
||||
|
@ -262,7 +270,7 @@ public class Cocos2dxSound {
|
|||
while (iter.hasNext()) {
|
||||
final Entry<String, ArrayList<Integer>> entry = iter.next();
|
||||
for (final int steamID : entry.getValue()) {
|
||||
this.mSoundPool.setVolume(steamID, this.mLeftVolume, this.mRightVolume);
|
||||
this.mSoundPool.setVolume(steamID, left, right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -346,6 +354,14 @@ public class Cocos2dxSound {
|
|||
this.mSoundPool.autoResume();
|
||||
}
|
||||
|
||||
void setAudioFocus(boolean isFocus) {
|
||||
mIsAudioFocus = isFocus;
|
||||
float leftVolume = mIsAudioFocus ? mLeftVolume : 0.0f;
|
||||
float rightVolume = mIsAudioFocus ? mRightVolume : 0.0f;
|
||||
|
||||
setEffectsVolumeInternal(leftVolume, rightVolume);
|
||||
}
|
||||
|
||||
// ===========================================================
|
||||
// Inner and Anonymous Classes
|
||||
// ===========================================================
|
||||
|
|
|
@ -46,6 +46,8 @@ THE SOFTWARE.
|
|||
|
||||
void cocos_android_app_init(JNIEnv* env) __attribute__((weak));
|
||||
|
||||
void cocos_audioengine_focus_change(int focusChange);
|
||||
|
||||
using namespace cocos2d;
|
||||
|
||||
extern "C"
|
||||
|
@ -56,21 +58,20 @@ extern "C"
|
|||
#if __ANDROID_API__ > 19
|
||||
#include <signal.h>
|
||||
#include <dlfcn.h>
|
||||
typedef __sighandler_t (*bsd_signal_func_t)(int, __sighandler_t);
|
||||
bsd_signal_func_t bsd_signal_func = NULL;
|
||||
typedef __sighandler_t (*bsd_signal_func_t)(int, __sighandler_t);
|
||||
bsd_signal_func_t bsd_signal_func = NULL;
|
||||
|
||||
__sighandler_t bsd_signal(int s, __sighandler_t f) {
|
||||
if (bsd_signal_func == NULL) {
|
||||
// For now (up to Android 7.0) this is always available
|
||||
bsd_signal_func = (bsd_signal_func_t) dlsym(RTLD_DEFAULT, "bsd_signal");
|
||||
__sighandler_t bsd_signal(int s, __sighandler_t f) {
|
||||
if (bsd_signal_func == NULL) {
|
||||
// For now (up to Android 7.0) this is always available
|
||||
bsd_signal_func = (bsd_signal_func_t) dlsym(RTLD_DEFAULT, "bsd_signal");
|
||||
|
||||
if (bsd_signal_func == NULL) {
|
||||
__android_log_assert("", "bsd_signal_wrapper", "bsd_signal symbol not found!");
|
||||
}
|
||||
if (bsd_signal_func == NULL) {
|
||||
__android_log_assert("", "bsd_signal_wrapper", "bsd_signal symbol not found!");
|
||||
}
|
||||
}
|
||||
return bsd_signal_func(s, f);
|
||||
}
|
||||
|
||||
return bsd_signal_func(s, f);
|
||||
}
|
||||
#endif // __ANDROID_API__ > 19
|
||||
|
||||
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved)
|
||||
|
@ -123,6 +124,11 @@ JNIEXPORT jintArray Java_org_cocos2dx_lib_Cocos2dxActivity_getGLContextAttrs(JNI
|
|||
return glContextAttrsJava;
|
||||
}
|
||||
|
||||
JNIEXPORT void Java_org_cocos2dx_lib_Cocos2dxAudioFocusManager_nativeOnAudioFocusChange(JNIEnv* env, jobject thiz, jint focusChange)
|
||||
{
|
||||
cocos_audioengine_focus_change(focusChange);
|
||||
}
|
||||
|
||||
JNIEXPORT void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnSurfaceChanged(JNIEnv* env, jobject thiz, jint w, jint h)
|
||||
{
|
||||
cocos2d::Application::getInstance()->applicationScreenSizeChanged(w, h);
|
||||
|
|
Loading…
Reference in New Issue