三星S 2 i 9100の音声放送の崩壊(CocosDeshion)を解決する
2638 ワード
三星S 2 i 9100機のサブサウンドドライブにバグがあり、SoundPoolの再生音が多すぎるとクラッシュする.弾丸の連続射撃の音響効果はこの機械ではほとんど必殺技だ.
cococos 2 d-xはこの問題を解決し、OpenSLを使用した.これはOpenGLのような音声基準であり、android 2.3以上のシステムがサポートされている. i 9100以外のデバイスはSoundPoolを使用し、i 9100デバイスはOpenSLを使用して音響効果を再生する. cococos 2 d-xの音声再生エンジンCocosDeshionにはまだ瑕疵があり、OpenSLでファイルを読み取る際にAssetsManagerを使用したが、SDカードのサウンドファイル読み取りはサポートされていない.私のゲームの実現は、すべてのリソースをpakファイルにパッケージ化し、音声を再生するときにSDカードに対応するファイルがなければSDカードに音声をコピーし、SDカードの音声ファイルを再生することです. 明らかにcococos 2 d−xはこの方式と互換性がない.
変更は簡単です.OpenSLEngine.cppファイルでgetFileDescriptor関数を変更します.
コードに示すように、リソースがapkパケット内のリソースでない場合、fopenを使用してファイルハンドルfdを取得します.
cococos 2 d-xはこの問題を解決し、OpenSLを使用した.これはOpenGLのような音声基準であり、android 2.3以上のシステムがサポートされている. i 9100以外のデバイスはSoundPoolを使用し、i 9100デバイスはOpenSLを使用して音響効果を再生する. cococos 2 d-xの音声再生エンジンCocosDeshionにはまだ瑕疵があり、OpenSLでファイルを読み取る際にAssetsManagerを使用したが、SDカードのサウンドファイル読み取りはサポートされていない.私のゲームの実現は、すべてのリソースをpakファイルにパッケージ化し、音声を再生するときにSDカードに対応するファイルがなければSDカードに音声をコピーし、SDカードの音声ファイルを再生することです. 明らかにcococos 2 d−xはこの方式と互換性がない.
変更は簡単です.OpenSLEngine.cppファイルでgetFileDescriptor関数を変更します.
int getFileDescriptor(const char * filename, off_t & start, off_t & length, bool inapk)
{
if (!inapk) {
FILE* fp = fopen(filename, "rb");
fseek(fp, 0, SEEK_END);
length = ftell(fp);
fseek(fp, 0, SEEK_SET);
start = 0;
return fileno(fp);
} else {
JniMethodInfo methodInfo;
if (! getStaticMethodInfo(methodInfo, ASSET_MANAGER_GETTER, "()Landroid/content/res/AssetManager;"))
{
methodInfo.env->DeleteLocalRef(methodInfo.classID);
return FILE_NOT_FOUND;
}
jobject assetManager = methodInfo.env->CallStaticObjectMethod(methodInfo.classID, methodInfo.methodID);
methodInfo.env->DeleteLocalRef(methodInfo.classID);
AAssetManager* (*AAssetManager_fromJava)(JNIEnv* env, jobject assetManager);
AAssetManager_fromJava = (AAssetManager* (*)(JNIEnv* env, jobject assetManager))
dlsym(s_pAndroidHandle, "AAssetManager_fromJava");
AAssetManager* mgr = AAssetManager_fromJava(methodInfo.env, assetManager);
assert(NULL != mgr);
AAsset* (*AAssetManager_open)(AAssetManager* mgr, const char* filename, int mode);
AAssetManager_open = (AAsset* (*)(AAssetManager* mgr, const char* filename, int mode))
dlsym(s_pAndroidHandle, "AAssetManager_open");
AAsset* Asset = AAssetManager_open(mgr, filename, AASSET_MODE_UNKNOWN);
if (NULL == Asset)
{
LOGD("file not found! Stop preload file: %s", filename);
return FILE_NOT_FOUND;
}
// open asset as file descriptor
int (*AAsset_openFileDescriptor)(AAsset* asset, off_t* outStart, off_t* outLength);
AAsset_openFileDescriptor = (int (*)(AAsset* asset, off_t* outStart, off_t* outLength))
dlsym(s_pAndroidHandle, "AAsset_openFileDescriptor");
int fd = AAsset_openFileDescriptor(Asset, &start, &length);
assert(0 <= fd);
void (*AAsset_close)(AAsset* asset);
AAsset_close = (void (*)(AAsset* asset))
dlsym(s_pAndroidHandle, "AAsset_close");
AAsset_close(Asset);
return fd;
}
}
コードに示すように、リソースがapkパケット内のリソースでない場合、fopenを使用してファイルハンドルfdを取得します.