æè¿ããããèªãã§ãããšãã«ã Android NDKãšOpenALã«é¢ããèšäºãèŠãŸãã ã ãŸããã³ã¡ã³ãã§ã¯ãOpenSL ESã«ã€ããŠè³ªåããããŸããã ããããããã®ã©ã€ãã©ãªã«é¢ããèšäºãæžããšããã¢ã€ãã¢ãæãã€ããŸããã NDKã®C ++ã§èšè¿°ãããAndroidã²ãŒã ã«ãµãŠã³ããšé³æ¥œãè¿œå ããå¿ èŠããããšãã«ããã®ãããã¯ãæ±ããŸããã èšäºã¯å®å šã§ãããšäž»åŒµããŠããŸãããåºæ¬ã ãããããŸãã
å 容ïŒ
- OpenSL ESæ§é ã®ç°¡åãªèª¬æ
- ã©ã€ãã©ãªã¡ã«ããºã ã®åæåãšã¹ããŒã«ãŒãæäœããããã®ãªããžã§ã¯ãã®äœæ
- PCMãã¬ã€ïŒwavïŒ
- MP3ãã¬ã€ãOGG
- ãããã«
1.æ§é ã®ç°¡åãªèª¬æ
OpenSL ESã§ã®äœæ¥ã¯ãCèšèªã®æ¬äŒŒãªããžã§ã¯ãæåã®æ§é ã«åºã¥ããŠããŸãã ãããžã§ã¯ããCã§èšè¿°ãããŠããå Žåã«äœ¿çšãããŸããããªããžã§ã¯ãæåã®ã¢ãããŒããå¿ èŠã§ãã äžè¬ã«ãæ¬äŒŒãªããžã§ã¯ãæåæ§é ã¯ãC ++ã®ããã«ããã ãæ瀺çã«ãæ§é ãžã®ãã€ã³ã¿ãŒãæåã®åŒæ°ãšããŠåãåãé¢æ°ãžã®ãã€ã³ã¿ãŒãå«ãéåžžã®Cèšèªæ§é ã§ãã
OpenSL ESã«ã¯ãäžèšã®2ã€ã®äž»ãªã¿ã€ãã®æ§é ããããŸãã
- ãªããžã§ã¯ã ïŒSLObjectItfïŒã¯ãç¹å®ã®ç¯å²ã®ã¿ã¹ã¯ãå®è¡ãããããã®ãªãœãŒã¹ã«é¢ããæ å ±ãä¿åããããã«èšèšãããäžé£ã®ãªãœãŒã¹ã®æœè±¡åã§ãã ãªããžã§ã¯ããäœæãããšããã®ã¿ã€ãã決å®ãããŸããããã«ããããã«ãã䜿çšããŠè§£æ±ºã§ããã¿ã¹ã¯ã®ç¯å²ã決å®ãããŸãã ãªããžã§ã¯ãã¯Javaèšèªã®ãªããžã§ã¯ãã«äŒŒãŠãããC ++ã®ã¯ã©ã¹ã®ããã«èããããšãã§ããŸã
- ã€ã³ã¿ãŒãã§ã€ã¹ ïŒSLEngineItfãSLPlayItfãSLSeekItfãªã©ïŒã¯ãç¹å®ã®ãªããžã§ã¯ãã«ãã£ãŠæäŸãããäžé£ã®çžäºã«é¢é£ããæ©èœã®æœè±¡åã§ãã ã€ã³ã¿ãŒãã§ã€ã¹ã«ã¯ããªããžã§ã¯ãã«å¯ŸããŠã¢ã¯ã·ã§ã³ãå®è¡ããããã«äœ¿çšãããå€ãã®ã¡ãœãããå«ãŸããŠããŸãã ã€ã³ã¿ãŒãã§ã€ã¹ã¯ããã®ã€ã³ã¿ãŒãã§ã€ã¹ã§ãµããŒããããã¡ãœããã®æ£ç¢ºãªãªã¹ããå®çŸ©ããã¿ã€ãã§ãã ã€ã³ã¿ãŒãã§ã€ã¹ã¯èå¥åã«ãã£ãŠå®çŸ©ãããŸãããã®èå¥åã¯ãã€ã³ã¿ãŒãã§ã€ã¹ã®çš®é¡ãåç §ããããã«ã³ãŒãã§äœ¿çšã§ããŸãã
ç°¡åã«èšãã°ããªãœãŒã¹ãå²ãåœãŠãŠã€ã³ã¿ãŒãã§ã€ã¹ãååŸããã«ã¯ãªããžã§ã¯ããå¿ èŠã§ãããã€ã³ã¿ãŒãã§ã€ã¹ã¯ãªããžã§ã¯ãã®æ©èœãžã®ã¢ã¯ã»ã¹ãæäŸããŸãã 1ã€ã®ãªããžã§ã¯ãã«è€æ°ã®ã€ã³ã¿ãŒãã§ã€ã¹ãå«ããããšãã§ããŸãã ããã€ã¹ã«ãã£ãŠã¯ãäžéšã®ã€ã³ã¿ãŒãã§ã€ã¹ãå©çšã§ããªãå ŽåããããŸãã ããããç§ã¯ããã«ééããŠããŸããã
2.ã©ã€ãã©ãªã¡ã«ããºã ã®åæåãšãã¹ããŒã«ãŒãæäœããããã®ãªããžã§ã¯ãã®äœæ
OpenSL ESãAndroid NDKã«æ¥ç¶ããã«ã¯ãlOpenSLESãã©ã°ãAndroid.mkãã¡ã€ã«ã®LOCAL_LDLIBSã»ã¯ã·ã§ã³ã«è¿œå ããã ãã§ãã
LOCAL_LDLIBS := /*...*/ -lOpenSLES
䜿çšãããããããŒãã¡ã€ã«ïŒ
#include <SLES/OpenSLES.h> #include <SLES/OpenSLES_Android.h>
OpenSL ESã§ã®äœæ¥ãéå§ããã«ã¯ãslCreateEngineãåŒã³åºããŠOpenSL ESãšã³ãžã³ãªããžã§ã¯ãïŒSLObjectItfïŒãåæåããSL_IID_ENGINEã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããŠäœæ¥ããããšã瀺ãå¿ èŠããããŸãã ããã¯ãä»ã®ãªããžã§ã¯ããäœæã§ããããã«ããããã«å¿ èŠã§ãã ãã®ãããªåŒã³åºãã«ãã£ãŠååŸããããªããžã§ã¯ãã¯ãOpenSL ES APIã«ã¢ã¯ã»ã¹ããããã®äžå¿çãªãªããžã§ã¯ãã«ãªããŸãã 次ã«ããªããžã§ã¯ãã¯Realizeæ¬äŒŒã¡ãœããã䜿çšããŠå®è£ ããå¿ èŠããããŸããããã¯ãC ++ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã«é¡äŒŒããŠããŸãã Realizeã®æåã®ãã©ã¡ãŒã¿ãŒã¯ãå®è£ ãããŠãããªããžã§ã¯ãïŒããã«é¡äŒŒïŒã瀺ãã2çªç®ã¯ãªããžã§ã¯ããéåæãã©ããã瀺ãasyncãã©ã°ã§ãã
çŸåšã®Android NDKå®è£ ã§ã¯ãäžè¬çã«1ã€ã®ã©ã€ãã©ãªãšã³ãžã³ãšæ倧32åã®ãªããžã§ã¯ããäœæã§ããŸãã ãã ãããªããžã§ã¯ããäœæããæäœã¯å€±æããå ŽåããããŸãïŒããšãã°ãã·ã¹ãã ãªãœãŒã¹ã®äžè¶³ãåå ïŒã
ã©ã€ãã©ãªãšã³ãžã³ã®åæå
SLObjectItf engineObj; const SLInterfaceID pIDs[1] = {SL_IID_ENGINE}; const SLboolean pIDsRequired[1] = {SL_TRUE}; SLresult result = slCreateEngine( &engineObj, /* */ 0, /* */ NULL, /* , NULL, */ 1, /* , */ pIDs, /* ID */ pIDsRequired /* , , . SL_TRUE, , , SL_RESULT_FEATURE_UNSUPPORTED*/ ); /* . slCreateEngine â */ if(result != SL_RESULT_SUCCESS){ LOGE("Error after slCreateEngine"); return; } /* . this*/ result = (*engineObj)->Realize(engineObj, SL_BOOLEAN_FALSE); // /* , */ if(result != SL_RESULT_SUCCESS){ LOGE("Error after Realize engineObj"); return; }
次ã«ãSL_IID_ENGINEã€ã³ã¿ãŒãã§ã€ã¹ãååŸããå¿ èŠããããŸãããã®ã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããŠãã¹ããŒã«ãŒãé³æ¥œããµãŠã³ããªã©ã«ã¢ã¯ã»ã¹ã§ããŸãã
ã€ã³ã¿ãŒãã§ãŒã¹SL_IID_ENGINEã®ååŸ
SLEngineItf engine; result = (*engineObj)->GetInterface( engineObj, /*this*/ SL_IID_ENGINE, /*ID */ &engine /* */ );
ãªããžã§ã¯ããæ±ãäžè¬çãªã¹ããŒã ã«ã€ããŠå°ã説æããŸãããã
- ç®çã®ã€ã³ã¿ãŒãã§ã€ã¹ãæå®ããŠãªããžã§ã¯ããååŸããŸã
-
(*obj)->Realize(obj, async);
åŒã³åºããŠå®è£ ã(*obj)->Realize(obj, async);
-
(*obj)-> GetInterface (obj, ID, &itf);
åŒã³åºããŠãå¿ èŠãªã€ã³ã¿ãŒãã§ã€ã¹ãååŸããŸã(*obj)-> GetInterface (obj, ID, &itf);
- ã€ã³ã¿ãŒãã§ã€ã¹ãæäœãã
-
(*obj)->Destroy(obj);
åŒã³åºããŠãªããžã§ã¯ããåé€ããŸã(*obj)->Destroy(obj);
ã¹ããŒã«ãŒãæäœããã«ã¯ãengineObjãªããžã§ã¯ãã®ãšã³ãžã³ã€ã³ã¿ãŒãã§ã€ã¹ã®æ¬äŒŒã¡ãœããCreateOutputMixã䜿çšããŠoutputMixObjãªããžã§ã¯ããäœæããŸãïŒããã¯æãã ããªã®ã§ãèªè ã¯ãªããžã§ã¯ããšã€ã³ã¿ãŒãã§ã€ã¹ãåºå¥ã§ããããã«ãªããŸãïŒã ãã®ãªããžã§ã¯ãã¯åŸã§é³å£°åºåã®ããã«å¿ èŠã«ãªããŸãã
ã¹ããŒã«ãŒãæäœããããã®ãªããžã§ã¯ããäœæãã
SLObjectItf outputMixObj; const SLInterfaceID pOutputMixIDs[] = {}; const SLboolean pOutputMixRequired[] = {}; /* slCreateEngine()*/ result = (*engine)->CreateOutputMix(engine, &outputMixObj, 0, pOutputMixIDs, pOutputMixRequired); result = (*outputMixObj)->Realize(outputMixObj, SL_BOOLEAN_FALSE);
SLOutputMixItfã¯ãé³å£°åºåããã€ã¹ïŒã¹ããŒã«ãŒãããããã©ã³ïŒãè¡šããªããžã§ã¯ãã§ãã OpenSL ESä»æ§ã¯ãå©çšå¯èœãªI / Oããã€ã¹ã®ãªã¹ããååŸããæ©èœãæäŸããŸãããAndroid NDKã®å®è£ ã¯ååã«å®äºããŠããããããã€ã¹ã®ãªã¹ãã®ååŸãå¿ èŠãªããã€ã¹ã®éžæããµããŒãããŠããŸããïŒå ¬åŒã«ã¯SLAudioIODeviceCapabilitiesItfãããã察象ãšããŠããŸãïŒã
3. PCMã®åçïŒwavïŒ
ç°¡åã«ããããã«ãWAVããããŒã®ããŒã¿ã¯äœ¿çšããªãããšãããã«èšããªããã°ãªããŸããã å¿ èŠã«å¿ããŠããã®ãµããŒããè¿œå ããã®ã¯ç°¡åã§ãã ããã§ãèŠåºãã¯ããŒã¿ã®ãµã€ãºãæ£ãã決å®ããããã«ã®ã¿å¿ èŠã§ãã
PCMãããã¡ãŒã®äœ¿çš
struct WAVHeader{ char RIFF[4]; unsigned long ChunkSize; char WAVE[4]; char fmt[4]; unsigned long Subchunk1Size; unsigned short AudioFormat; unsigned short NumOfChan; unsigned long SamplesPerSec; unsigned long bytesPerSec; unsigned short blockAlign; unsigned short bitsPerSample; char Subchunk2ID[4]; unsigned long Subchunk2Size; }; struct SoundBuffer{ WAVHeader* header; char* buffer; int length; }; /* PCM AAssetManager:*/ SoundBuffer* loadSoundFile(const char* filename){ SoundBuffer* result = new SoundBuffer(); AAsset* asset = AAssetManager_open(assetManager, filename, AASSET_MODE_UNKNOWN); off_t length = AAsset_getLength(asset); result->length = length - sizeof(WAVHeader); result->header = new WAVHeader(); result->buffer = new char[result->length]; AAsset_read(asset, result->header, sizeof(WAVHeader)); AAsset_read(asset, result->buffer, result->length); AAsset_close(asset); return result; }
ããã§ã¯ãã¯ã€ãã¯ãããã¡ãªãŒãã£ãªåºåãèšå®ããŸãããã ãã®ããã«ãç¹å¥ãªæ¡åŒµæ©èœSLDataLocator_AndroidSimpleBufferQueueã䜿çšããŸãã ãŸããé³æ¥œãåçããã«ã¯ãSLDataSourceãšSLDataSinkã®2ã€ã®æ§é ãå ¥åããå¿ èŠããããŸãããããã¯ããããããªãŒãã£ãªãã£ãã«ã®å ¥åãšåºåãèšè¿°ããŠããŸãã
ãããã¡ãªã³ã°ããããªãŒãã£ãªåºåèšå®
Android NDKã§ã®OpenSL ESã®å®è£ ã¯å³å¯ã§ã¯ãããŸããã äžéšã®ã€ã³ã¿ãŒãã§ã€ã¹ãæå®ãããŠããªãå Žåãããã¯ååŸã§ããªããšããæå³ã§ã¯ãããŸããã ãããããããããªãæ¹ãè¯ãã§ã ã èªåã®äžã«SL_IID_PLAYã€ã³ã¿ãŒãã§ã€ã¹ã瀺ããŸãã
/*, CreateAudioPlayer() */ SLDataLocator_AndroidSimpleBufferQueue locatorBufferQueue = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 1}; /* */ /*, wav*/ SLDataFormat_PCM formatPCM = { SL_DATAFORMAT_PCM, 1, SL_SAMPLINGRATE_44_1, SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16, SL_SPEAKER_FRONT_CENTER, SL_BYTEORDER_LITTLEENDIAN }; SLDataSource audioSrc = {&locatorBufferQueue, &formatPCM}; SLDataLocator_OutputMix locatorOutMix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObj}; SLDataSink audioSnk = {&locatorOutMix, NULL}; const SLInterfaceID pIDs[1] = {SL_IID_BUFFERQUEUE}; const SLboolean pIDsRequired[1] = {SL_BOOLEAN_TRUE }; /* */ result = (*engine)->CreateAudioPlayer(engine, &playerObj, &audioSrc, &audioSnk, 1, pIDs, pIDsRequired); result = (*playerObj)->Realize(playerObj, SL_BOOLEAN_FALSE);
Android NDKã§ã®OpenSL ESã®å®è£ ã¯å³å¯ã§ã¯ãããŸããã äžéšã®ã€ã³ã¿ãŒãã§ã€ã¹ãæå®ãããŠããªãå Žåãããã¯ååŸã§ããªããšããæå³ã§ã¯ãããŸããã ãããããããããªãæ¹ãè¯ãã§ã ã èªåã®äžã«SL_IID_PLAYã€ã³ã¿ãŒãã§ã€ã¹ã瀺ããŸãã
SLPlayItf player; result = (*playerObj)->GetInterface(playerObj, SL_IID_PLAY, &player); SLBufferQueueItf bufferQueue; result = (*playerObj)->GetInterface(playerObj, SL_IID_BUFFERQUEUE, &bufferQueue); result = (*player)->SetPlayState(player, SL_PLAYSTATE_PLAYING);
SL_IID_PLAYããã³SL_IID_BUFFERQUEUEã«å ããŠã次ã®ãããªä»ã®ã€ã³ã¿ãŒãã§ã€ã¹ããªã¯ãšã¹ãã§ããŸãã
- ããªã¥ãŒã ã³ã³ãããŒã«çšã®SL_IID_VOLUME
- ãã£ãã«ç®¡ççšã®SL_IID_MUTESOLOïŒãã«ããã£ãã«ãªãŒãã£ãªã®ã¿ã®å Žåãããã¯SLDataFormat_PCMæ§é äœã®numChannelsãã£ãŒã«ãã«ç€ºãããŸãïŒã
- ãšãã§ã¯ããéãåãããããã®SL_IID_EFFECTSENDïŒä»æ§ã«ãã-ãªããŒãå¹æã®ã¿ïŒ
ãªã©
(*player)->SetPlayState(player, SL_PLAYSTATE_PLAYING);
æ°ããäœæããããã¬ãŒã€ãŒããªã³ã«ããŸãã ãã¥ãŒã空ã®éãç¡é³ã®ã¿ãèãããŸãã é³ããã¥ãŒã«å ¥ããŸãããã
ãã¥ãŒã«ãµãŠã³ããè¿œå ãã
SoundBuffer* sound = loadSoundFile("mySound.wav"); (*soundsBufferQueue)->Clear(bufferQueue); /* , - . , , */ (*soundsBufferQueue)->Enqueue(bufferQueue, sound->buffer, sound->length); /* SoundBuffer, */
ããã ãã§ããæãåçŽãªwavãã¬ãŒã€ãŒã¯æºåãã§ããŠããŸãã
ä»æ§ã«ãããããããAndroid NDKã¯PCM以å€ã®åœ¢åŒã®é³æ¥œã®ãããã¡ãŒåºåããµããŒãããŠããªãããšã«æ³šæããŠãã ããã
4. MP3åçãOGG
äžèšã®ã¹ããŒã ã¯ãé·ãé³æ¥œãã¡ã€ã«ã®åçã«ã¯é©ããŠããŸããã ãŸããé·ãwavãã¡ã€ã«ã®ééãéåžžã«å€§ãããªãããã§ãã MP3ãŸãã¯OGGã䜿çšããããšããå§ãããŸãã OpenSL ESã¯ãããã«äœ¿çšã§ããã¹ããªãŒãã³ã°ãã¡ã€ã«ããµããŒãããŠããŸãã ãããã¡ãªã³ã°ãããåºåãšã®éãã¯ãé³æ¥œãã¡ã€ã«ããšã«åå¥ã®ãã¬ãŒã€ãŒãªããžã§ã¯ããäœæããå¿ èŠãããããšã§ãã ãã®ãã¬ãŒã€ãŒã®åçäžã«ãã¡ã€ã«ãå€æŽããããšã¯ã§ããŸããã
é³æ¥œãåçããæºåãããŸãã
ãã¡ã€ã«åŸ©å·åããŒã«ã䜿çšãã
struct ResourseDescriptor{ int32_t decriptor; off_t start; off_t length; }; /* AAssetManager*/ ResourseDescriptor loadResourceDescriptor(const char* path){ AAsset* asset = AAssetManager_open(assetManager, path, AASSET_MODE_UNKNOWN); ResourseDescriptor resourceDescriptor; resourceDescriptor.decriptor = AAsset_openFileDescriptor(asset, &resourceDescriptor.start, &resourceDescriptor.length); AAsset_close(asset); return resourceDescriptor; }
次ã«ãSLDataSourceãšSLDataSinkãååºŠå ¥åããŸãã ãããŠããªãŒãã£ãªãã¬ãŒã€ãŒãäœæããŸãã
ãã¬ã€ã€ãŒäœæ
ResourseDescriptor resourceDescriptor = loadResourceDescriptor("myMusic.mp3"); SLDataLocator_AndroidFD locatorIn = { SL_DATALOCATOR_ANDROIDFD, resourseDescriptor.decriptor, resourseDescriptor.start, resourseDescriptor.length } SLDataFormat_MIME dataFormat = { SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED }; SLDataSource audioSrc = {&locatorIn, &dataFormat}; SLDataLocator_OutputMix dataLocatorOut = { SL_DATALOCATOR_OUTPUTMIX, outputMixObj }; SLDataSink audioSnk = {&dataLocatorOut, NULL}; const SLInterfaceID pIDs[2] = {SL_IID_PLAY, SL_IID_SEEK}; const SLboolean pIDsRequired[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE}; SLObjectItf playerObj; SLresult result = (*engine)->CreateAudioPlayer(engine, &playerObj, &audioSrc, &audioSnk, 2, pIDs, pIDsRequired); result = (*playerObj)->Realize(playerObj, SL_BOOLEAN_FALSE);
ãœãŒã¹ããŒã¿ãèšè¿°ããããã«ãMIMEã¿ã€ãã䜿çšããŸããããã«ããããã¡ã€ã«ã¿ã€ããèªåæ€åºãããŸãã
次ã«ãã€ã³ã¿ãŒãã§ã€ã¹SL_IID_PLAYããã³SL_IID_SEEKãååŸããŸãã åŸè ã¯ããã¡ã€ã«å ã®åçäœçœ®ãšã«ãŒããå€æŽããããã«å¿ èŠã§ãã åçç¶æ ãšé床ã«é¢ä¿ãªã䜿çšã§ããŸãã
ã€ã³ã¿ãŒãã§ã€ã¹ã®ååŸ
SLPlayItf player; result = (*playerObj)->GetInterface(playerObj, SL_IID_PLAY, &player); SLSeekItf seek; result = (*playerObj)->GetInterface(playerObj, SL_IID_SEEK, &seek); (*seek)->SetLoop( seek, SL_BOOLEAN_TRUE, /* */ 0, /* (0 )*/ SL_TIME_UNKNOWN /* */ ); (*player)->SetPlayState(player, SL_PLAYSTATE_PLAYING);
çè«çã«ã¯ãã«ãŒãã¡ã«ããºã ã¯ã²ãŒã ã®ããã¯ã°ã©ãŠã³ããã¥ãŒãžãã¯ã®èšå®ã«äŸ¿å©ã§ãã å®éã«ã¯ãäœæ²ã®çµäºããéå§ãŸã§ã®éã«0.5ã1.0ç§ãçµéããŸãïŒèŽèŠã®æéãããŸããŸãªããã€ã¹ã«æµ®ãã¶ïŒã ããã¯ã°ã©ãŠã³ããã¥ãŒãžãã¯ã®éäžãšçµãããã¹ã ãŒãºã«ãã§ãŒããããããšã§ããããå æããŸããã T.O. ã®ã£ããã¯èŠããŸããã
ä»æ§ã«ããã°ãããŸããŸãªã³ãŒã«ããã¯ãSLPlayItfã€ã³ã¿ãŒãã§ãŒã¹ã§ãã³ã°ãããããšãã§ããŸãã Androidã§ã¯ãNDKæ©èœã¯ãµããŒããããŠããŸããïŒã¡ãœããã¯SL_RESULT_SUCCESSãè¿ããŸãããã³ãŒã«ããã¯ã¯æ©èœããŸããïŒã
ãã¬ãŒã€ãŒãåæ¢ãŸãã¯äžæåæ¢ããã«ã¯ãSLPlayItfã€ã³ã¿ãŒãã§ã€ã¹ã®SetPlayStateã¡ãœããã䜿çšããå€SL_PLAYSTATE_STOPPEDãŸãã¯SL_PLAYSTATE_PAUSEDããããã䜿çšã§ããŸãã GetPlayStateã¡ãœããã¯åãå€ãè¿ãããã¬ãŒã€ãŒã®ç¶æ ã調ã¹ãŸãã
5.çµè«
OpenSL ES APIã¯éåžžã«è±å¯ã§ããµãŠã³ãã®åçã«å ããŠãé²é³ããããšãã§ããŸãã ããã§ã¯ããµãŠã³ãã¬ã³ãŒãã£ã³ã°ã«ã€ããŠã¯è§ŠããŸããããããã¯éåžžã«ããŸãæ©èœããŠãããšèšãã ãã§ãã ããŒã¿ãååŸããã«ã¯ããããã¡ãã¥ãŒã䜿çšãããŸãã ããŒã¿ã¯PCM圢åŒã§ãã
ã©ã€ãã©ãªã¯ãã¯ãã¹ãã©ãããã©ãŒã éçºã§äœ¿çšããã®ãå°é£ã§ãã å€ãã®æ©èœã¯ãAndroidå°çšã®ã¡ãœããã«ãã£ãŠå®è£ ãããŸãã ããã«ãããããããç§ã«ã¯éåžžã«å¿«é©ã«æããŸããã
çæã§ã¯ãç¡æã®å®è£ ãèŠãããä»æ§ããã®å€ãã®ãã®ã¯ãµããŒããããŠããŸããã ããã«ããã®APIã¯Android SDKã§äœ¿çšå¯èœãªAPIãããé«éã§ã¯ãããŸããã
æåŠ
- ã·ã«ãŽã¡ã³ã¬ã¿ãã€ã«ã Android NDKã C / C ++ã§ã®Androidåãã®ã¢ããªã±ãŒã·ã§ã³éçºã
- ã¯ããã¹ã°ã«ãŒãæ ªåŒäŒç€Ÿ OpenSL ESä»æ§ ã
åªãããããå®å šãªã³ãŒãäŸã¯ãæšæºã®Android NDKïŒNativeAudioãããžã§ã¯ãïŒã«ãããŸãã
Android NDKå šè¬ãç¹ã«OpenSL ESã䜿çšããå¿ èŠæ§ã«ã€ããŠã®è³ªåãäºæ³ããŠãããã«åçããŸãã Android NDKã¯ãæåãªã²ãŒã éçºäŒç€Ÿã®ãã¹ãã¿ã¹ã¯ã®æ¡ä»¶ã«å¿ èŠã§ããïŒããã§ã®ã³ã³ãã¹ãããããŸããïŒã åŸã«ããã¯ç§ã«ãšã£ãŠææŠã«ãªããŸãããä»äºãçŸããä»äžããããšã¯ã§ããŸããã ã¹ã¢ãã°ã OpenSL ESã¯æ°ãŸããã«éžæããŸãã ç§ã¯åœŒãOpenALãšäžç·ã«ä»äºãããçµéšããããŸããã§ããããã®ãããJavaã§ã®æç»åŒã³åºãã¯anã解決çã ãšèããŸããã