bool FSLESSoundSource::CreatePlayer() { // data info SLDataLocator_AndroidSimpleBufferQueue LocationBuffer = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 1 }; // PCM Info SLDataFormat_PCM PCM_Format = { SL_DATAFORMAT_PCM, SLuint32(Buffer->NumChannels), SLuint32( Buffer->SampleRate * 1000 ), SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16, Buffer->NumChannels == 2 ? ( SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT ) : SL_SPEAKER_FRONT_CENTER, SL_BYTEORDER_LITTLEENDIAN }; SLDataSource SoundDataSource = { &LocationBuffer, &PCM_Format}; // configure audio sink SLDataLocator_OutputMix Output_Mix = { SL_DATALOCATOR_OUTPUTMIX, ((FSLESAudioDevice *)AudioDevice)->SL_OutputMixObject}; SLDataSink AudioSink = { &Output_Mix, NULL}; // create audio player const SLInterfaceID ids[] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME}; const SLboolean req[] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; SLresult result = (*Device->SL_EngineEngine)->CreateAudioPlayer( Device->SL_EngineEngine, &SL_PlayerObject, &SoundDataSource, &AudioSink, sizeof(ids) / sizeof(SLInterfaceID), ids, req ); if(result != SL_RESULT_SUCCESS) { UE_LOG( LogAndroidAudio, Fatal,TEXT("FAILED OPENSL BUFFER CreateAudioPlayer 0x%x"), result); return false; } bool bFailedSetup = false; // realize the player result = (*SL_PlayerObject)->Realize(SL_PlayerObject, SL_BOOLEAN_FALSE); if(result != SL_RESULT_SUCCESS) { UE_LOG( LogAndroidAudio, Fatal,TEXT("FAILED OPENSL BUFFER Realize 0x%x"), result); return false; } // get the play interface result = (*SL_PlayerObject)->GetInterface(SL_PlayerObject, SL_IID_PLAY, &SL_PlayerPlayInterface); if(result != SL_RESULT_SUCCESS) { UE_LOG( LogAndroidAudio, Fatal,TEXT("FAILED OPENSL BUFFER GetInterface SL_IID_PLAY 0x%x"), result); bFailedSetup |= true; } // volume result = (*SL_PlayerObject)->GetInterface(SL_PlayerObject, SL_IID_VOLUME, &SL_VolumeInterface); if(result != SL_RESULT_SUCCESS) { UE_LOG( LogAndroidAudio, Fatal,TEXT("FAILED OPENSL BUFFER GetInterface SL_IID_VOLUME 0x%x"), result); bFailedSetup |= true; } // buffer system result = (*SL_PlayerObject)->GetInterface(SL_PlayerObject, SL_IID_BUFFERQUEUE, &SL_PlayerBufferQueue); if(result != SL_RESULT_SUCCESS) { UE_LOG( LogAndroidAudio, Fatal,TEXT("FAILED OPENSL BUFFER GetInterface SL_IID_BUFFERQUEUE 0x%x"), result); bFailedSetup |= true; } return bFailedSetup == false; }
xnAudioSource* xnAudioSourceCreate(xnAudioListener* listener, int sampleRate, int maxNBuffers, npBool mono, npBool spatialized, npBool streamed) { (void)spatialized; auto res = new xnAudioSource; res->listener = listener; res->sampleRate = sampleRate; res->mono = mono; res->streamed = streamed; res->looped = false; SLDataFormat_PCM format; format.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16; format.samplesPerSec = 1000 * SLuint32(sampleRate); //milliHz format.numChannels = mono ? 1 : 2; format.containerSize = 16; format.formatType = SL_DATAFORMAT_PCM; format.endianness = SL_BYTEORDER_LITTLEENDIAN; format.channelMask = mono ? SL_SPEAKER_FRONT_CENTER : SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; SLDataLocator_AndroidSimpleBufferQueue bufferQueue = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, (SLuint32) maxNBuffers }; SLDataSource audioSrc = { &bufferQueue, &format }; SLDataLocator_OutputMix outMix = { SL_DATALOCATOR_OUTPUTMIX, listener->audioDevice->outputMix }; SLDataSink sink = { &outMix, NULL }; const SLInterfaceID ids[3] = { *SL_IID_BUFFERQUEUE_PTR, *SL_IID_VOLUME_PTR, *SL_IID_PLAYBACKRATE_PTR }; const SLboolean req[3] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE }; auto result = (*listener->audioDevice->engine)->CreateAudioPlayer(listener->audioDevice->engine, &res->object, &audioSrc, &sink, 3, ids, req); if (result != SL_RESULT_SUCCESS) { DEBUG_BREAK; delete res; return NULL; } res->canRateChange = true; result = (*res->object)->Realize(res->object, SL_BOOLEAN_FALSE); if (result != SL_RESULT_SUCCESS) { res->canRateChange = false; result = (*listener->audioDevice->engine)->CreateAudioPlayer(listener->audioDevice->engine, &res->object, &audioSrc, &sink, 2, ids, req); if (result != SL_RESULT_SUCCESS) { DEBUG_BREAK; delete res; return NULL; } result = (*res->object)->Realize(res->object, SL_BOOLEAN_FALSE); if (result != SL_RESULT_SUCCESS) { DEBUG_BREAK; delete res; return NULL; } } result = (*res->object)->GetInterface(res->object, *SL_IID_PLAY_PTR, &res->player); if (result != SL_RESULT_SUCCESS) { DEBUG_BREAK; delete res; return NULL; } result = (*res->object)->GetInterface(res->object, *SL_IID_BUFFERQUEUE_PTR, &res->queue); if (result != SL_RESULT_SUCCESS) { DEBUG_BREAK; delete res; return NULL; } result = (*res->object)->GetInterface(res->object, *SL_IID_VOLUME_PTR, &res->volume); if (result != SL_RESULT_SUCCESS) { DEBUG_BREAK; delete res; return NULL; } if (res->canRateChange) { //For some reason this was not working in Android N... result = (*res->object)->GetInterface(res->object, *SL_IID_PLAYBACKRATE_PTR, &res->playRate); if (result != SL_RESULT_SUCCESS) { DEBUG_BREAK; delete res; return NULL; } } result = (*res->volume)->EnableStereoPosition(res->volume, SL_BOOLEAN_TRUE); if (result != SL_RESULT_SUCCESS) { DEBUG_BREAK; delete res; return NULL; } result = (*res->queue)->RegisterCallback(res->queue, QueueCallback, res); if (result != SL_RESULT_SUCCESS) { DEBUG_BREAK; delete res; return NULL; } result = (*res->player)->RegisterCallback(res->player, PlayerCallback, res); if (result != SL_RESULT_SUCCESS) { DEBUG_BREAK; delete res; return NULL; } result = (*res->player)->SetCallbackEventsMask(res->player, SL_PLAYEVENT_HEADMOVING); if (result != SL_RESULT_SUCCESS) { DEBUG_BREAK; delete res; return NULL; } listener->audioDevice->deviceLock.Lock(); listener->audioDevice->sources.insert(res); listener->audioDevice->deviceLock.Unlock(); return res; }