PDA

View Full Version : Adding Audio Effects in android



bitfield
08-23-2013, 03:55 AM
Hi Erik

The OpenSL document specifies Interfaces for audio effects such as equalizer, bass boost, preset reverberation, stereo widening etc. OpenSL ES supports bass boost via SLBassBoostItf. So I used this interface but i'm not getting any effect..so pls resolve the problem..

Erik
08-27-2013, 12:21 AM
Hi Bitfield,

I am assuming that you've read sections 4.5.1 and 8.13 of the (OpenSL ES 1.1) specification . Using the BassBoostItf is fairly straight forward.

The SLBassBoost interface is an optional interface, so you have to start by checking that it's supported by your device and your object. You didn't mention if you are using it on the audio player or the output mix object, but the method is the same:
res = (*player)->GetInterface(player, SL_IID_BASSBOST, (void *)&BassBoostItf);
if ( res != SL_RESULT_SUCCESS ) exit -1;

If the result doesn't equal SL_RESULT_SUCCESS, the interface cannot be used, and the value in BassBoostItf is undefined. Note that the system may return a previous handle to an interface and may accept calls but fail internally.

Now that you have your interface, you will need to enable the bass boost and set the strength. The result value will be key to debugging:
res = (*BassBoostItf)->SetEnabled(BassBoostItf, SL_BOOLEAN_TRUE);
res = (*BassBoostItf)->IsEnabled(BassBoostItf, &isEnabled); /* Verify bass boost is enabled */

res = (*BassBoostItf)->IsStrengthSupported(BassBoostItf, &isSupported); /* Is strength supported? */
if(isSupported == SL_BOOLEAN_TRUE)
{
res = (*BassBoostItf)->SetStrength(BassBoostItf, 1000); /* Max strength */
res = (*BassBoostItf)->GetRoundedStrength(BassBoostItf, &roundedStrength); /*Check to see what the system set */
}

Hope this helps

Erik

bitfield
08-27-2013, 04:23 AM
Hi Erik,

Thanks for your reply,I did the same thing previously i debugged and checked it I am getting SL_RESULT_SUCCESS.I have attached BassBoost Inteface to output mix i tried it with audio player also,but still there is no effect.I checked it on HTC oneX,Samsung NOTE2,NOTE1.I am not getting any errors..but there is no effect.My project depends on this issue.

Expecting for your reply,

Thanks & Regards
Bitfield.

bitfield
08-28-2013, 04:09 AM
Hi Erik,
I am waiting for your reply.The actual bass effect check it in power amp music player there the bass will be extreme..but by using opensl es in android i am not getting that effect.

Erik
08-28-2013, 04:15 AM
Bitfield,

Without seeing the code in question it's hard to say why it is failing. The code snippet I provided has been successfully tested on a conformant implementation and worked, but I haven't tested it on Android. Remember, there may be other things running on the device which affect the results. Do you have other effects working and it's only the bass boost which isn't working, or is this the first effect you are trying?

If you haven't done so already, I suggest writing a small test application which only tests that portion of code - bass boost on playback without any other effects. Once you get a small application working, then take a look at what's different between the two.

Sorry I can't be of more help at this point, but without details it's going to be hard to help you resolve the issue.

Erik

bitfield
08-28-2013, 05:20 AM
Hi Erik,
Thanks for your reply,I am providing the code what i did..yes it is impossible to say why it is failing..sorry for the inconvenience. Here i am using asset audio player i am exposing bassboost to this player.Previously i checked with reverb effect.Reverb is the first effect i tried i did not got any effect so i tried of checking with bassboost..so for this i faced the same problem no effect.So please resolve the issue by checking the code(don't check about reverb problem).The red color code is where I exposed BassBoost.The bassboost effect is easy to identify..so i exposed directly to player and i played the music after exposing to player. previously i maintained a status based on the status i enabling or disabling bassboost but in this case also i did not got any effect.



#include <assert.h>
#include <jni.h>
#include <string.h>

// for __android_log_print(ANDROID_LOG_INFO, "YourApp", "formatted message");
// #include <android/log.h>

// for native audio
#include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h>

// for native asset manager
#include <sys/types.h>
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
#include <android/log.h>


// engine interfaces
static SLObjectItf engineObject = NULL;
static SLEngineItf engineEngine;

// output mix interfaces
static SLObjectItf outputMixObject = NULL;
static SLEnvironmentalReverbItf outputMixEnvironmentalReverb = NULL;

// buffer queue player interfaces
static SLObjectItf bqPlayerObject = NULL;
static SLPlayItf bqPlayerPlay;
static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
static SLEffectSendItf bqPlayerEffectSend;
static SLMuteSoloItf bqPlayerMuteSolo;
static SLVolumeItf bqPlayerVolume;
SLBassBoostItf bassboost;

// aux effect on the output mix, used by the buffer queue player
static const SLEnvironmentalReverbSettings reverbSettings =
SL_I3DL2_ENVIRONMENT_PRESET_STONECORRIDOR;

// URI player interfaces
static SLObjectItf uriPlayerObject = NULL;
static SLPlayItf uriPlayerPlay;
static SLSeekItf uriPlayerSeek;
static SLMuteSoloItf uriPlayerMuteSolo;
static SLVolumeItf uriPlayerVolume;

// file descriptor player interfaces
static SLObjectItf fdPlayerObject = NULL;
static SLPlayItf fdPlayerPlay;
static SLSeekItf fdPlayerSeek;
static SLMuteSoloItf fdPlayerMuteSolo;
static SLVolumeItf fdPlayerVolume;
SLEqualizerItf equalizer;
SLVirtualizerItf virtualizer;
// recorder interfaces
static SLObjectItf recorderObject = NULL;
static SLRecordItf recorderRecord;
static SLAndroidSimpleBufferQueueItf recorderBufferQueue;

// synthesized sawtooth clip
#define SAWTOOTH_FRAMES 8000
static short sawtoothBuffer[SAWTOOTH_FRAMES];

// 5 seconds of recorded audio at 16 kHz mono, 16-bit signed little endian
#define RECORDER_FRAMES (16000 * 5)
static short recorderBuffer[RECORDER_FRAMES];
static unsigned recorderSize = 0;
static SLmilliHertz recorderSR;


// create the engine and output mix objects
void Java_com_example_nativeaudio_NativeAudio_createEng ine(JNIEnv* env,jclass clazz)
{
SLresult result;

// create engine
result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
assert(SL_RESULT_SUCCESS == result);
(void) result;

// realize the engine
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
(void) result;

// get the engine interface, which is needed in order to create other objects

result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE,&engineEngine);
assert(SL_RESULT_SUCCESS == result);
(void) result;

// create output mix, with environmental reverb specified as a non-required interface

const SLInterfaceID ids[1] = { SL_IID_ENVIRONMENTALREVERB };
const SLboolean req[1] = { SL_BOOLEAN_FALSE };
result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject,1, ids, req);
assert(SL_RESULT_SUCCESS == result);
(void) result;

// realize the output mix
result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
(void) result;

}






// create asset audio player
jboolean Java_com_example_nativeaudio_NativeAudio_createAss etAudioPlayer(JNIEnv* env, jclass clazz, jobject assetManager, jstring filename)
{
SLresult result;

// convert Java string to UTF-8

const char *utf8 = (*env)->GetStringUTFChars(env, filename, NULL);
assert(NULL != utf8);

// use asset manager to open asset by filename

AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);
assert(NULL != mgr);
AAsset* asset = AAssetManager_open(mgr, utf8, AASSET_MODE_UNKNOWN);

// release the Java string and UTF-8

(*env)->ReleaseStringUTFChars(env, filename, utf8);

// the asset might not be found
if (NULL == asset)
{
return JNI_FALSE;
}

// open asset as file descriptor
off_t start, length;
int fd = AAsset_openFileDescriptor(asset, &start, &length);
assert(0 <= fd);
AAsset_close(asset);

// configure audio source
SLDataLocator_AndroidFD loc_fd = { SL_DATALOCATOR_ANDROIDFD, fd, start,length };

SLDataFormat_MIME format_mime = { SL_DATAFORMAT_MIME, NULL,SL_CONTAINERTYPE_UNSPECIFIED };
SLDataSource audioSrc = { &loc_fd, &format_mime };

// configure audio sink
SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX,outputMixObject };
SLDataSink audioSnk = { &loc_outmix, NULL };

// create audio player
const SLInterfaceID ids[4] = { SL_IID_SEEK, SL_IID_MUTESOLO, SL_IID_VOLUME,SL_IID_BASSBOOST};
const SLboolean req[4] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE,SL_BOOLEAN_TRUE};

result = (*engineEngine)->CreateAudioPlayer(engineEngine, &fdPlayerObject,&audioSrc, &audioSnk, 5, ids, req);
assert(SL_RESULT_SUCCESS == result);
(void) result;

// realize the player
result = (*fdPlayerObject)->Realize(fdPlayerObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
(void) result;

// get the play interface
result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_PLAY,&fdPlayerPlay);
assert(SL_RESULT_SUCCESS == result);
(void) result;

// get the seek interface
result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_SEEK,&fdPlayerSeek);
assert(SL_RESULT_SUCCESS == result);
(void) result;

// get the mute/solo interface
result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_MUTESOLO,&fdPlayerMuteSolo);
assert(SL_RESULT_SUCCESS == result);
(void) result;

// get the volume interface
result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_VOLUME,&fdPlayerVolume);
assert(SL_RESULT_SUCCESS == result);
(void) result;

result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_BASSBOOST,(void *) &bassboost);


if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo", "result not sucess");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo", "result sucess");

result = (*bassboost)->SetEnabled(bassboost, SL_BOOLEAN_TRUE);

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo","result not set enabled sucess");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo","result set enabled sucess");

SLboolean isEnabled, isSupported;
result = (*bassboost)->IsEnabled(bassboost, &isEnabled); /* Verify bass boost is enabled */

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo","result not enabled sucess");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo","result enabled sucess");

result = (*bassboost)->IsStrengthSupported(bassboost, &isSupported); /* Is strength supported? */

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo","result is strength not supported");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo","result is strength supported");


result = (*bassboost)->SetStrength(bassboost, 1000); /* Max strength */

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo","result set strength not supported");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo","result set strength supported");

SLint32 roundedStrength = 0;
result = (*bassboost)->GetRoundedStrength(bassboost, &roundedStrength); /*Check to see what the system set */

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo","result no round strength supported");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo", "The value is %d",
roundedStrength);


result = (*fdPlayerSeek)->SetLoop(fdPlayerSeek, SL_BOOLEAN_TRUE, 0,
SL_TIME_UNKNOWN);
assert(SL_RESULT_SUCCESS == result);
(void) result;

return JNI_TRUE;
}

// set the playing state for the asset audio player
void Java_com_example_nativeaudio_NativeAudio_setPlayin gAssetAudioPlayer(
JNIEnv* env, jclass clazz, jboolean isPlaying) {
SLresult result;

// make sure the asset audio player was created
if (NULL != fdPlayerPlay) {

// set the player's state
result = (*fdPlayerPlay)->SetPlayState(fdPlayerPlay,
isPlaying ? SL_PLAYSTATE_PLAYING : SL_PLAYSTATE_PAUSED);
assert(SL_RESULT_SUCCESS == result);
(void) result;
}

}

}

Thanks & Regards
Bitfield

Erik
08-28-2013, 06:19 AM
Bitfield,

I noticed you aren't using the SLEffectSendItf interface on the player. SLEffectSendItf controls how much an effect from a player contributes to the overall audio chain. See section 8.16 in the 1.0.1 spec.

Since an effect can be used both on the player and on the output mix, the effect on the player is considered an auxiliary effect to the output mix effect. The SLEfectSendItf controls how much the auxiliary effect will contribute. The default level is 0.

If that doesn't resolve the issue, I would separate out initializing the player with setting up your effects. Then try turning your effect on and off while playing a continuous steady sound so that you can easily hear if turning the effect on and off has any effect on the audio.

bitfield
08-28-2013, 07:49 AM
Hi Erik,

I used SLEffectSendItf interface on the player by using the below code but i am facing some problem i.e error which is mentioned below:(SLEffectSendItf is created i.e realized i got SL_RESULT_SUCCESS but when i enabling then i am facing below errors) So please resolve the issue by checking the code.


EffectSend on unknown aux effect 0x5e7ff940


Leaving EffectSend::EnableEffectSend (SL_RESULT_PARAMETER_INVALID)
Log:no enable effect send

EffectSend on unknown aux effect 0x5e7ff940

Leaving EffectSend::IsEnabled (SL_RESULT_PARAMETER_INVALID)

Log:not enable

Leaving EffectSend::SetDirectLevel (SL_RESULT_PARAMETER_INVALID)
Log: no set direct level


Leaving EffectSend::SetSendLevel
Log:no set send level



// create asset audio player
jboolean Java_com_example_nativeaudio_NativeAudio_createAss etAudioPlayer(
JNIEnv* env, jclass clazz, jobject assetManager, jstring filename) {
SLresult result;

// convert Java string to UTF-8
const char *utf8 = (*env)->GetStringUTFChars(env, filename, NULL);
assert(NULL != utf8);

// use asset manager to open asset by filename
AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);
assert(NULL != mgr);
AAsset* asset = AAssetManager_open(mgr, utf8, AASSET_MODE_UNKNOWN);

// release the Java string and UTF-8
(*env)->ReleaseStringUTFChars(env, filename, utf8);

// the asset might not be found
if (NULL == asset) {
return JNI_FALSE;
}

// open asset as file descriptor
off_t start, length;
int fd = AAsset_openFileDescriptor(asset, &start, &length);
assert(0 <= fd);
AAsset_close(asset);

// configure audio source
SLDataLocator_AndroidFD loc_fd = { SL_DATALOCATOR_ANDROIDFD, fd, start,
length };
SLDataFormat_MIME format_mime = { SL_DATAFORMAT_MIME, NULL,
SL_CONTAINERTYPE_UNSPECIFIED };
SLDataSource audioSrc = { &loc_fd, &format_mime };

// configure audio sink
SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX,
outputMixObject };
SLDataSink audioSnk = { &loc_outmix, NULL };

// create audio player
const SLInterfaceID ids[5] = { SL_IID_SEEK, SL_IID_MUTESOLO, SL_IID_VOLUME,
SL_IID_BASSBOOST,SL_IID_EFFECTSEND};
const SLboolean req[5] =
{ SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE,
SL_BOOLEAN_TRUE,SL_BOOLEAN_TRUE};
result = (*engineEngine)->CreateAudioPlayer(engineEngine, &fdPlayerObject,
&audioSrc, &audioSnk, 5, ids, req);
assert(SL_RESULT_SUCCESS == result);
(void) result;

// realize the player
result = (*fdPlayerObject)->Realize(fdPlayerObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
(void) result;

// get the play interface
result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_PLAY,
&fdPlayerPlay);
assert(SL_RESULT_SUCCESS == result);
(void) result;

// get the seek interface
result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_SEEK,
&fdPlayerSeek);
assert(SL_RESULT_SUCCESS == result);
(void) result;

// get the mute/solo interface
result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_MUTESOLO,
&fdPlayerMuteSolo);
assert(SL_RESULT_SUCCESS == result);
(void) result;

// get the volume interface
result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_VOLUME,
&fdPlayerVolume);
assert(SL_RESULT_SUCCESS == result);
(void) result;

result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_EFFECTSEND,
(void *) &effect);

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo", "effect send not created");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo", "effect send created");


result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_BASSBOOST,
(void *) &bassboost);

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo", "bass boost not created");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo", "bass boost created");


result = (*bassboost)->SetEnabled(bassboost, SL_BOOLEAN_TRUE);

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo",
"result not set enabled sucess");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo",
"result set enabled sucess");

SLboolean isEnabled, isSupported;
result = (*bassboost)->IsEnabled(bassboost, &isEnabled); /* Verify bass boost is enabled */

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo",
"result not enabled sucess");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo",
"result enabled sucess");

result = (*bassboost)->IsStrengthSupported(bassboost, &isSupported); /* Is strength supported? */

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo",
"result is strength not supported");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo",
"result is strength supported");

result = (*bassboost)->SetStrength(bassboost, 1000); /* Max strength */

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo",
"result set strength not supported");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo",
"result set strength supported");

SLint32 roundedStrength = 0;
result = (*bassboost)->GetRoundedStrength(bassboost, &roundedStrength); /*Check to see what the system set */

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo",
"result no round strength supported");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo", "The value is %d",
roundedStrength);


result = (*effect)->EnableEffectSend(effect,bassboost,SL_BOOLEAN_TRUE, (SLmillibel) 0);

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo","no enable effect send");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo", " enable effect send");


SLboolean enableEffect;
result = (*effect)->IsEnabled(effect,bassboost,&enableEffect);

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo","not enable");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo", " enabled");

result = (*effect)->SetDirectLevel(effect,1);

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo","no set direct level");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo", "set direct level");

result = (*effect)->SetSendLevel(effect,bassboost,1);

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo","no set send level");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo", "set send level");


result = (*fdPlayerSeek)->SetLoop(fdPlayerSeek, SL_BOOLEAN_TRUE, 0,
SL_TIME_UNKNOWN);
assert(SL_RESULT_SUCCESS == result);
(void) result;

return JNI_TRUE;
}

Thanks & Regards
Bitfield

Erik
08-28-2013, 11:29 AM
Bitfield,

I suggest you look at the example code in B.6.1 Environmental Reverb in the 1.0.1 spec for an example of how to use SLEffectSendItf. Since you mentioned you first tried with environmental reverb, you might try to to implement example B.6.1 (stripping out the 3D effects) to see if you can get it to work, and then add the bass boost.

In your code, the call
result = (*effect)->EnableEffectSend(effect,bassboost,SL_BOOLEAN_TRUE ,(SLmillibel) 0);
should be
result = (*effect)->EnableEffectSend(effect, &bassboost, SL_BOOLEAN_TRUE , (SLmillibel) 0);

See page 508 of the 1.0.1 spec for a usage example.

Erik

bitfield
08-29-2013, 02:10 AM
Hi Erik,
First I need to mention about SLEffectSendItf..yesterday i checked with both the lines mentioned below:

result = (*effect)->EnableEffectSend(effect,bassboost,SL_BOOLEAN_TR UE ,(SLmillibel) 0);
result = (*effect)->EnableEffectSend(effect, &bassboost, SL_BOOLEAN_TRUE , (SLmillibel) 0);

i faced error in both the cases.

and the other thing is that today i tried with reverb i did not got any effect
1. i am not facing any errors & i am getting SL_RESULT_SUCCESS.

I exposed reverb on output mix to identify reverb effect on button click(i am calling enableReverb) i.e enabling reverb.Here i am not facing any effectsend errors which are mentioned in previous post.So please resolve the issue by checking the code.


i used below code for reverb:
// create the engine and output mix objects
void Java_com_example_nativeaudio_NativeAudio_createEng ine(JNIEnv* env,jclass clazz)
{

SLresult result;

// create engine
result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
assert(SL_RESULT_SUCCESS == result);
(void) result;

// realize the engine
result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
(void) result;

// get the engine interface, which is needed in order to create other objects
result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE,
&engineEngine);
assert(SL_RESULT_SUCCESS == result);
(void) result;


// create output mix, with environmental reverb specified as a non-required interface
const SLInterfaceID ids[1] = { SL_IID_ENVIRONMENTALREVERB };
const SLboolean req[1] = { SL_BOOLEAN_TRUE };
result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject,
1, ids, req);
assert(SL_RESULT_SUCCESS == result);
(void) result;

// realize the output mix
result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
(void) result;

result = (*outputMixObject)->GetInterface(outputMixObject,SL_IID_ENVIRONMENTALR EVERB, (void *) &outputMixEnvironmentalReverb);

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo","result env reverb failure");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo", "result env reverb success");

result = (*outputMixEnvironmentalReverb)->SetEnvironmentalReverbProperties(outputMixEnvironm entalReverb,&reverbSettings);

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo","result not set properties fail");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo","result set properties ");

result = (*outputMixEnvironmentalReverb)->SetReverbLevel(outputMixEnvironmentalReverb,2000);

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo","reverb level failure");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo","reverb level success");


SLpermille reverbStrength = 0;

result = (*outputMixEnvironmentalReverb)->GetReverbLevel(outputMixEnvironmentalReverb,&reverbStrength);

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo","no strength in reverb");
else
__android_log_print(ANDROID_LOG_DEBUG,"demo", "the value is= %d",reverbStrength);

result = (*outputMixEnvironmentalReverb)->SetDiffusion(outputMixEnvironmentalReverb,1000);

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo","set diffusion failure");
else
__android_log_print(ANDROID_LOG_DEBUG,"demo", "set diffusion success");

}

// create asset audio player
jboolean Java_com_example_nativeaudio_NativeAudio_createAss etAudioPlayer(JNIEnv* env, jclass clazz, jobject assetManager, jstring filename)
{

SLresult result;

// convert Java string to UTF-8
const char *utf8 = (*env)->GetStringUTFChars(env, filename, NULL);
assert(NULL != utf8);

// use asset manager to open asset by filename
AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);
assert(NULL != mgr);
AAsset* asset = AAssetManager_open(mgr, utf8, AASSET_MODE_UNKNOWN);

// release the Java string and UTF-8
(*env)->ReleaseStringUTFChars(env, filename, utf8);

// the asset might not be found
if (NULL == asset)
{
return JNI_FALSE;
}

// open asset as file descriptor
off_t start, length;
int fd = AAsset_openFileDescriptor(asset, &start, &length);
assert(0 <= fd);
AAsset_close(asset);

// configure audio source
SLDataLocator_AndroidFD loc_fd = { SL_DATALOCATOR_ANDROIDFD, fd, start,length };
SLDataFormat_MIME format_mime = { SL_DATAFORMAT_MIME, NULL,SL_CONTAINERTYPE_UNSPECIFIED };
SLDataSource audioSrc = { &loc_fd, &format_mime };

// configure audio sink
SLDataLocator_OutputMix loc_outmix = { SL_DATALOCATOR_OUTPUTMIX,
outputMixObject };
SLDataSink audioSnk = { &loc_outmix, NULL };


const SLInterfaceID ids[3] = {SL_IID_PLAY,SL_IID_SEEK,SL_IID_EFFECTSEND};
const SLboolean req[3] ={ SL_BOOLEAN_TRUE,SL_BOOLEAN_TRUE,SL_BOOLEAN_TRUE};

result = (*engineEngine)->CreateAudioPlayer(engineEngine, &fdPlayerObject,
&audioSrc, &audioSnk, 3, ids, req);
assert(SL_RESULT_SUCCESS == result);
(void) result;

// realize the player
result = (*fdPlayerObject)->Realize(fdPlayerObject, SL_BOOLEAN_FALSE);
assert(SL_RESULT_SUCCESS == result);
(void) result;

// get the play interface
result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_PLAY,
&fdPlayerPlay);
assert(SL_RESULT_SUCCESS == result);
(void) result;

// get the seek interface
result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_SEEK,
&fdPlayerSeek);
assert(SL_RESULT_SUCCESS == result);
(void) result;

result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_EFFECTSEND,(void *) &effect);

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo", "effect send not created");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo", "effect send created");



result = (*fdPlayerPlay)->SetPlayState(fdPlayerPlay,SL_PLAYSTATE_PLAYING);


return JNI_TRUE;
}

// set the playing state for the asset audio player
void Java_com_example_nativeaudio_NativeAudio_setPlayin gAssetAudioPlayer(
JNIEnv* env, jclass clazz, jboolean isPlaying) {
SLresult result;

// make sure the asset audio player was created
if (NULL != fdPlayerPlay) {

// set the player's state
result = (*fdPlayerPlay)->SetPlayState(fdPlayerPlay,
isPlaying ? SL_PLAYSTATE_PLAYING : SL_PLAYSTATE_PAUSED);
assert(SL_RESULT_SUCCESS == result);
(void) result;
}

}


// enable reverb on the buffer queue player
jboolean Java_com_example_nativeaudio_NativeAudio_enableRev erb(JNIEnv* env,
jclass clazz, jboolean enabled) {
SLresult result;

// we might not have been able to add environmental reverb to the output mix
if (NULL == outputMixEnvironmentalReverb) {
return JNI_FALSE;
}

result = (*effect)->EnableEffectSend(effect,outputMixEnvironmentalReve rb,SL_BOOLEAN_TRUE, (SLmillibel) 0);

result = (*effect)->EnableEffectSend(effect,&outputMixEnvironmentalReverb,SL_BOOLEAN_TRUE, (SLmillibel) 0);

if i use the red color code i am facing error mentioned below.

EffectSend on unknown aux effect 0x57748010

Leaving EffectSend::EnableEffectSend (SL_RESULT_PARAMETER_INVALID)

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo","not enabled effect send");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo", " enabled effect send");

result = (*effect)->SetSendLevel(effect,outputMixEnvironmentalReverb,( SLmillibel)0);

if (result != SL_RESULT_SUCCESS)
__android_log_print(ANDROID_LOG_DEBUG, "demo","no send level");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo", "send level success");

SLboolean isEnabled = JNI_FALSE;

result = (*effect)->IsEnabled(effect,outputMixEnvironmentalReverb,&isEnabled);

if (isEnabled != JNI_TRUE)
__android_log_print(ANDROID_LOG_DEBUG, "demo","not enabled");
else
__android_log_print(ANDROID_LOG_DEBUG, "demo", "enabled");

return JNI_TRUE;
}

Thanks & Regards
Bitfield

Erik
08-29-2013, 09:16 AM
Bitfield,

Which version of Android are you using on these devices? I asked the working group to help take a look at it to see if they can see what's happening.

bitfield
08-29-2013, 10:27 AM
I tested on HTC oneX,Samsung Note 1, Samsung Note 2, all are of android 4.1.1 version.

bitfield
08-30-2013, 11:02 PM
Hi Erik,

I am expecting for your reply.If you have any issues i will share the screens for you..

Thanks & Regards
Bitfield

dalayya
09-04-2013, 02:41 AM
have you got any result-->bitfield

bitfield
09-04-2013, 04:08 AM
No I did not any effect dalayya.Erik said that he will discuss with his development team till now I did not got anything waiting for reply.Do you have any idea about that.

Erik
09-05-2013, 01:14 AM
Hi Bitfield,

I wanted to give you an update:
We have reviewed your code and can't find anything obviously wrong. One of our members have offered to dig deeper into it, but he will be doing that in his spare time. Hopefully he will have an answer for you soon.

We noticed that you are using the sample code from the NDK as a base for your project. Have you tested the unmodified sample code on your devices? I assume that it works for you as expected.

Unfortunately I don't have any more information for you at this time.

bitfield
09-05-2013, 04:06 AM
Hi Erik,
First I tested the sample code from the NDK without modifying it on my devices like HTC ONEX, Samsung NOTE1 & NOTE2,the sample project contains only reverb effect i tested it on my 3 devices but i am unable to get any effect.I posted in android-ndk forums https://groups.google.com/forum/#!searchin/android-ndk/Audio$20Programming$20in$20android$20using$20opens l$20es/android-ndk/8R7r4_BFtLw/raHgOgFQat8J .. Glen Kasten (Google Developer) discussed with me he asked in which device you are checking..i have given reply that I am testing in NOTE1..after that he has not given any reply

Erik
09-06-2013, 12:10 AM
Hi Bitfield,

I know Glenn. He's one of the most knowledgeable people when it comes to the Android OpenSL ES implementation.

We had a member test the original example code from the Android NDK and it compiles and runs fine. The app has a button to enable/disable environmental reverb with buffer queue playback. The effect is obvious since it defaults to the stone corridor preset. The sample does not include bass boost, but it should be easy to add by copying and modifying the existing code. You would need to include new playback files since the bass boost won't be noticeable with the ones included.

I suggest you first try compiling and running the native-audio sample in the NDK unmodified to ensure that it works. If it doesn't, you need to figure out why before you go on to the bass boost.

Also, make sure you test the audio through headphones and not using the device speaker. The speaker in most devices is not good enough to properly render the effect.

I hope this helps you resolve your problem.

Best,

Erik

bitfield
09-12-2013, 06:59 AM
Hi Erik,
Based on your reply I tested the unmodified code on HTC ONEX,NOTE1,NOTE2 android 4.1.2 version unable to get reverb effect for buffer queue playback.Unfortunately I tested it on tab android version 4.1.1. There I am able to feel reverb effect.So what is the problem in other devices and the other things I need to ask which are mentioned below.

As reverb effect is attached to outputmix in ndk sample code.

1. when SLEffectSendItf is exposed for buffer queue playback I am getting effect.but when I create effect send interface for asset audio player.At that point I am unable to get reverb effect.Is there any difference when the music is played by using bufferqueue(using pcm decoded file) and asset(path of the file).

2.Is there any way to decode mp3 file to pcm format in opensl es.

bitfield
09-13-2013, 08:55 AM
I decoded mp3 using mediacodec in android and passed that byte data to bufferqueue i am getting noise..

Erik
10-07-2013, 10:34 AM
Hi Bitfield,

Sorry for the delay. I've been on travel.


Hi Erik,
Based on your reply I tested the unmodified code on HTC ONEX,NOTE1,NOTE2 android 4.1.2 version unable to get reverb effect for buffer queue playback.Unfortunately I tested it on tab android version 4.1.1. There I am able to feel reverb effect.So what is the problem in other devices and the other things I need to ask which are mentioned below.

As reverb effect is attached to outputmix in ndk sample code.

1. when SLEffectSendItf is exposed for buffer queue playback I am getting effect.but when I create effect send interface for asset audio player.At that point I am unable to get reverb effect.Is there any difference when the music is played by using bufferqueue(using pcm decoded file) and asset(path of the file).

2.Is there any way to decode mp3 file to pcm format in opensl es.

...

I decoded mp3 using mediacodec in android and passed that byte data to bufferqueue i am getting noise..


For the first part: I don't the difference between the two versions of Android, but if you are getting different results on two versions of the operating system, I suggest consulting an Android forum to see if they know any differences between the two versions.

For the second part:
1. When you are using an asset audio player, are you using the same content as for the buffer queue? From your description I believe that you have a file that you decode to PCM not through the OpenSL ES implementation and then submit it using the buffer queue. You are then getting the wanted result from the reverb. That is good. Then you play the original file through the system codec and using the same code except that you use a SLDataLocator_URI instead of SLDataLocator_BufferQueue. I can't explain it, but you should be getting the same results if you use the same input. Have you tried to load the PCM data through a file?

2. Yes and no. OpenSL ES was not really designed to do this - one reason is to protect DRM protected content. But *if* the system allows it, you can use a buffer queue as a data sink for the player. Support for this wasn't added until 1.1 when we added object chaining so that you can hook a recorder to a player object in order to do transcoding.

For your transcoding the MP3 into PCM and submitting it through a buffer queue, have you verified the pcm data using other means? Since you have successfully managed to submit through the buffer queue then you know the chain works. If you are getting noise then I would suspect your PCM data.

Best,

Erik