Hi,
I have been playing around with audio-echo (
https://github.com/googlesamples/android-ndk/tree/master/audio-echo) and I have faced some problems. I am trying to attach an equializer to the already published app, I know it will add more latency to the application. I have decided to attach it to the output mix but, despite it seems to be successfully created, it does not work. The code I have added is in red:
AudioPlayer::AudioPlayer(SampleFormat *sampleFormat, SLEngineItf slEngine) :
sLmillibelMax_(0), sLmillibelMin_(0), eQBandsNo_(0), freeQueue_(nullptr),
playQueue_(nullptr), devShadowQueue_(nullptr), callback_(nullptr)
{
SLresult result;
assert(sampleFormat);
sampleInfo_ = *sampleFormat;
SLboolean r[1] = {SL_BOOLEAN_TRUE};
SLInterfaceID ifac[1] = {SL_IID_EQUALIZER};
result = (*slEngine)->CreateOutputMix(slEngine, &outputMixObjectItf_, 1,
ifac, r); SLASSERT(result);
// realize the output mix
result = (*outputMixObjectItf_)->Realize(outputMixObjectItf_, SL_BOOLEAN_FALSE);
SLASSERT(result);
// configure audio source
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {
SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE,
DEVICE_SHADOW_BUFFER_QUEUE_LEN };
SLAndroidDataFormat_PCM_EX format_pcm;
ConvertToSLSampleFormat(&format_pcm, &sampleInfo_);
SLDataSource audioSrc = {&loc_bufq, &format_pcm};
// configure audio sink
SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObjectItf_};
SLDataSink audioSnk = {&loc_outmix, NULL};
/*
* create fast path audio player: SL_IID_BUFFERQUEUE and SL_IID_VOLUME interfaces ok,
* NO others!
*/
SLInterfaceID ids[2] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME};
SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
result = (*slEngine)->CreateAudioPlayer(slEngine, &playerObjectItf_,
&audioSrc, &audioSnk,
sizeof(ids)/sizeof(ids[0]), ids, req);
SLASSERT(result);
// realize the player
result = (*playerObjectItf_)->Realize(playerObjectItf_, SL_BOOLEAN_FALSE);
SLASSERT(result);
// get the play interface
result = (*playerObjectItf_)->GetInterface(playerObjectItf_, SL_IID_PLAY, &playItf_);
SLASSERT(result);
// get the buffer queue interface
result = (*playerObjectItf_)->GetInterface(playerObjectItf_, SL_IID_BUFFERQUEUE,
&playBufferQueueItf_);
SLASSERT(result);
// get the equalizer interface result = (*outputMixObjectItf_)->GetInterface(outputMixObjectItf_,
SL_IID_EQUALIZER, (void *)
&slEqualizerItf_);
SLASSERT(result); // register callback on the buffer queue
result = (*playBufferQueueItf_)->RegisterCallback(playBufferQueueItf_, bqPlayerCallback, this);
SLASSERT(result);
result = (*playItf_)->SetPlayState(playItf_, SL_PLAYSTATE_STOPPED);
SLASSERT(result);
// create an empty queue to track deviceQueue
devShadowQueue_ = new AudioQueue(DEVICE_SHADOW_BUFFER_QUEUE_LEN);
assert(devShadowQueue_);
#ifdef ENABLE_LOG
std::string name = "play";
logFile_ = new AndroidLog(name);
#endif
}
SLresult AudioPlayer::Start(void) {
SLuint32 state;
SLresult result = (*playItf_)->GetPlayState(playItf_, &state);
if (result != SL_RESULT_SUCCESS) {
return SL_BOOLEAN_FALSE;
}
if(state == SL_PLAYSTATE_PLAYING) {
return SL_BOOLEAN_TRUE;
}
result = (*playItf_)->SetPlayState(playItf_, SL_PLAYSTATE_STOPPED);
SLASSERT(result);
result = (*playItf_)->SetPlayState(playItf_, SL_PLAYSTATE_PLAYING);
SLASSERT(result);
result = (*slEqualizerItf_)->GetNumberOfBands(slEqualizerItf_,
&eQBandsNo_);
SLASSERT(result);
result = (*slEqualizerItf_)->GetBandLevelRange(slEqualizerItf_,
&sLmillibelMin_,
&sLmillibelMax_);
SLASSERT(result);
result = (*slEqualizerItf_)->SetBandLevel(slEqualizerItf_, 0,
sLmillibelMax_);
SLASSERT(result);
for (int b = 0; b < eQBandsNo_; ++b) {
result = (*slEqualizerItf_)->SetBandLevel(slEqualizerItf_, b,
sLmillibelMin_);
SLASSERT(result);
}
result = (*slEqualizerItf_)->SetEnabled(slEqualizerItf_, SL_BOOLEAN_TRUE);
SLASSERT(result);
SLboolean ret;
result = (*slEqualizerItf_)->IsEnabled(slEqualizerItf_, &ret);
SLASSERT(result); // send pre-defined audio buffers to device
int i = PLAY_KICKSTART_BUFFER_COUNT;
while(i--) {
sample_buf *buf;
if(!playQueue_->front(&buf)) //we have buffers for sure
break;
if(SL_RESULT_SUCCESS !=
(*playBufferQueueItf_)->Enqueue(playBufferQueueItf_, buf, buf->size_))
{
LOGE("====failed to enqueue (%d) in %s", i, __FUNCTION__);
return SL_BOOLEAN_FALSE;
} else {
playQueue_->pop();
devShadowQueue_->push(buf);
}
}
return SL_BOOLEAN_TRUE;
}
Does anyone have any thoughts of what I may be doing wrong?
Thanks in advance for the help.