StreamReader* AssetArchive::Asset::openWith(AAsset* peer) { if (_cachedSize == size_t(-1)) _cachedSize = AAsset_getLength(peer); off_t start, length; int fd = AAsset_openFileDescriptor(peer, &start, &length); if (fd < 0) { LOG(0, ".. '%s': no fd, using AssetReader\n", getUrl().c_str()); // Can't access directly - maybe its compressed etc. Use AssetReader return new AssetReader(this, peer); } else { // We can access directly - it's a memory mapped file FILE* file = fdopen(fd, "r"); return new AssetFileReader(this, peer, file, start, length); } }
StreamReader* AssetArchive::Asset::openRange(size_t offset, size_t size, StreamSource* source) { if (source == NULL) source = this; AssetArchive* arc = static_cast<AssetArchive*>(getRealLocator()); AAsset* peer = arc->openAsset(_name); if (peer == NULL) NIT_THROW_FMT(EX_IO, "Can't open asset '%s'", _name.c_str()); if (_cachedSize == size_t(-1)) _cachedSize = AAsset_getLength(peer); off_t start, length; int fd = AAsset_openFileDescriptor(peer, &start, &length); if (fd < 0) NIT_THROW_FMT(EX_IO, "Can't open handle asset '%s': asset without file descriptor", _name.c_str()); FILE* file = fdopen(fd, "r"); return new AssetFileReader(source, peer, file, start + offset, size); }
// create asset audio player bool createAssetAudioPlayer2(void* mgr, const char* utf8, char* tag) { SLresult result; assert(NULL != mgr); AAsset* asset = AAssetManager_open((AAssetManager*) mgr, utf8, AASSET_MODE_UNKNOWN); // 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[3] = {SL_IID_SEEK, SL_IID_MUTESOLO, SL_IID_VOLUME}; const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; result = (*engineEngine)->CreateAudioPlayer(engineEngine, &fd2PlayerObject, &audioSrc, &audioSnk, 3, ids, req); assert(SL_RESULT_SUCCESS == result); (void)result; // realize the player result = (*fdPlayerObject)->Realize(fd2PlayerObject, SL_BOOLEAN_FALSE); assert(SL_RESULT_SUCCESS == result); (void)result; // get the play interface result = (*fdPlayerObject)->GetInterface(fd2PlayerObject, SL_IID_PLAY, &fd2PlayerPlay); assert(SL_RESULT_SUCCESS == result); (void)result; // get the seek interface result = (*fdPlayerObject)->GetInterface(fd2PlayerObject, SL_IID_SEEK, &fd2PlayerSeek); assert(SL_RESULT_SUCCESS == result); (void)result; // get the mute/solo interface result = (*fdPlayerObject)->GetInterface(fd2PlayerObject, SL_IID_MUTESOLO, &fd2PlayerMuteSolo); assert(SL_RESULT_SUCCESS == result); (void)result; // get the volume interface result = (*fdPlayerObject)->GetInterface(fd2PlayerObject, SL_IID_VOLUME, &fd2PlayerVolume); assert(SL_RESULT_SUCCESS == result); (void)result; // enable whole file looping result = (*fdPlayerSeek)->SetLoop(fd2PlayerSeek, SL_BOOLEAN_FALSE, 0, SL_TIME_UNKNOWN); assert(SL_RESULT_SUCCESS == result); (void)result; return JNI_TRUE; }
bool Audio::createChannelFromAsset(const char* fname, int index) { SLresult result; Channel* channel = &this->channels[index]; if (channel->loaded == SL_BOOLEAN_TRUE) { this->closeChannel(index); } AAssetManager* mgr = engine->app->activity->assetManager; if (mgr == NULL) { engine->setLastError(ERR_ASSET_LOAD); LOGE("emo_audio: failed to load AAssetManager"); return false; } AAsset* asset = AAssetManager_open(mgr, fname, AASSET_MODE_UNKNOWN); if (asset == NULL) { engine->setLastError(ERR_ASSET_OPEN); LOGE("emo_audio: failed to open an audio file"); LOGE(fname); return false; } // open asset as file descriptor off_t start, length; int fd = AAsset_openFileDescriptor(asset, &start, &length); if (fd < 0) { engine->setLastError(ERR_ASSET_OPEN); LOGE("emo_audio: failed to open an audio file"); LOGE(fname); return false; } 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, this->outputMixObject}; SLDataSink audioSnk = {&loc_outmix, NULL}; // create audio player const SLInterfaceID player_ids[3] = {SL_IID_PLAY, SL_IID_VOLUME, SL_IID_SEEK}; const SLboolean player_req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; result = (*engineEngine)->CreateAudioPlayer(this->engineEngine, &channel->playerObject, &audioSrc, &audioSnk, 3, player_ids, player_req); if (SL_RESULT_SUCCESS != result) { engine->setLastError(ERR_AUDIO_ASSET_INIT); LOGE("emo_audio: failed to create an audio player"); return false; } // realize the player result = (*channel->playerObject)->Realize(channel->playerObject, SL_BOOLEAN_FALSE); if (SL_RESULT_SUCCESS != result) { engine->setLastError(ERR_AUDIO_ASSET_INIT); LOGE("emo_audio: failed to realize an audio player"); return false; } channel->loaded = SL_BOOLEAN_TRUE; // get the play interface result = (*channel->playerObject)->GetInterface(channel->playerObject, SL_IID_PLAY, &channel->playerPlay); if (SL_RESULT_SUCCESS != result) { engine->setLastError(ERR_AUDIO_ASSET_INIT); LOGE("emo_audio: failed to get an audio player interface"); return false; } // get the seek interface result = (*channel->playerObject)->GetInterface(channel->playerObject, SL_IID_SEEK, &channel->playerSeek); if (SL_RESULT_SUCCESS != result) { engine->setLastError(ERR_AUDIO_ASSET_INIT); LOGE("emo_audio: failed to get an audio seek interface"); return false; } // the volume interface result = (*channel->playerObject)->GetInterface(channel->playerObject, SL_IID_VOLUME, &channel->playerVolume); if (SL_RESULT_SUCCESS != result) { engine->setLastError(ERR_AUDIO_ASSET_INIT); LOGE("emo_audio: failed to create an audio volume interface"); return false; } return true; }
/* Play a buffer */ bool SoundPlayer::playAsset(const char *assetname) { SLresult result; // destroy file descriptor audio player object, and invalidate all associated interfaces if (fdPlayerObject != NULL) { (*fdPlayerObject)->Destroy(fdPlayerObject); fdPlayerObject = NULL; fdPlayerPlay = NULL; fdPlayerSeek = NULL; fdPlayerMuteSolo = NULL; fdPlayerVolume = NULL; } assert(NULL != mgr); AAsset* asset = AAssetManager_open(mgr, assetname, AASSET_MODE_UNKNOWN); // the asset might not be found if (NULL == asset) { return 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[3] = {SL_IID_SEEK, SL_IID_MUTESOLO, SL_IID_VOLUME}; 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); // realize the player result = (*fdPlayerObject)->Realize(fdPlayerObject, SL_BOOLEAN_FALSE); assert(SL_RESULT_SUCCESS == result); // get the play interface result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_PLAY, &fdPlayerPlay); assert(SL_RESULT_SUCCESS == result); // get the seek interface result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_SEEK, &fdPlayerSeek); assert(SL_RESULT_SUCCESS == result); // get the mute/solo interface result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_MUTESOLO, &fdPlayerMuteSolo); assert(SL_RESULT_SUCCESS == result); // get the volume interface result = (*fdPlayerObject)->GetInterface(fdPlayerObject, SL_IID_VOLUME, &fdPlayerVolume); assert(SL_RESULT_SUCCESS == result); // set the player's state result = (*fdPlayerPlay)->SetPlayState(fdPlayerPlay, SL_PLAYSTATE_PLAYING); assert(SL_RESULT_SUCCESS == result); return (result == SL_RESULT_SUCCESS); }
bool sl_bgm_load(const char* file_name) { if(!file_name) { return false; } struct sl_bgm* bgm = &(ENV.bgm); if(bgm->file_name && strcmp(file_name, bgm->file_name) == 0) { SLresult result = (*bgm->fdPlayerPlay)->SetPlayState(bgm->fdPlayerPlay, SL_PLAYSTATE_STOPPED); return result == SL_RESULT_SUCCESS; } _bgm_free(bgm); bgm->file_name = strdup(file_name); if(bgm->file_name == NULL) { return false; } AAsset* asset = AAssetManager_open(ENV.asset_mgr, file_name, AASSET_MODE_UNKNOWN); if(asset == NULL) { goto ERROR; } // open asset as file descriptor off_t start, length; int fd = AAsset_openFileDescriptor(asset, &start, &length); AAsset_close(asset); if(fd < 0) { goto ERROR; } // 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, ENV.outputMixObject}; SLDataSink audioSnk = {&loc_outmix, NULL}; // create audio player SLresult result; const SLInterfaceID ids[3] = {SL_IID_SEEK, SL_IID_MUTESOLO, SL_IID_VOLUME}; const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; result = (*ENV.engineEngine)->CreateAudioPlayer(ENV.engineEngine, &bgm->fdPlayerObject, &audioSrc, &audioSnk, 3, ids, req); _check_result(result); // realize the player result = (*bgm->fdPlayerObject)->Realize(bgm->fdPlayerObject, SL_BOOLEAN_FALSE); _check_result(result); // get the play interface result = (*bgm->fdPlayerObject)->GetInterface(bgm->fdPlayerObject, SL_IID_PLAY, &bgm->fdPlayerPlay); _check_result(result); // get the seek interface result = (*bgm->fdPlayerObject)->GetInterface(bgm->fdPlayerObject, SL_IID_SEEK, &bgm->fdPlayerSeek); _check_result(result); // get the volume interface result = (*bgm->fdPlayerObject)->GetInterface(bgm->fdPlayerObject, SL_IID_VOLUME, &bgm->fdPlayerVolume); _check_result(result); // enable whole file looping result = (*bgm->fdPlayerSeek)->SetLoop(bgm->fdPlayerSeek, SL_BOOLEAN_FALSE, 0, SL_TIME_UNKNOWN); _check_result(result); // set bgm stop result = (*bgm->fdPlayerPlay)->SetPlayState(bgm->fdPlayerPlay, SL_PLAYSTATE_STOPPED); _check_result(result); return true; ERROR: _bgm_free(bgm); return false; }