3

amrnb を PCM にデコードし、正しい pcm バッファーを Enqueue バッファーに入れます (PCM データは正しいと確信しています) が、音が聞こえません。そして、バッファをフィードするとき、ログ出力:

/AudioTrack(14857): obtainBuffer timed out (is the CPU pegged?)

私のコードは以下で、私の質問は次のとおりです。

  1. OpenSL ES を使用すると何か問題がありますか?
  2. OpenSL ES は実機でしか動作しないというのは本当ですか?

サンプルコード:

void AudioTest()
{    

    StartAudioPlay();

    while(1)
    {
          //decode AMR to PCM

      /* Convert to little endian and write to wav */

          //write buffer to buffer queue     
      AudioBufferWrite(littleendian, 320);

   }
}

void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context)
{

//do nothing

}

void AudioBufferWrite(const void* buffer, int size) 
{

    (*gBQBufferQueue)->Enqueue(gBQBufferQueue, buffer, size );

}

// create buffer queue audio player
void SlesCreateBQPlayer(/*AudioCallBackSL funCallback, void *soundMix,*/ int rate, int nChannel, int bitsPerSample ) 
{

    SLresult result;

    // configure audio source
    SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};

    SLDataFormat_PCM format_pcm = {SL_DATAFORMAT_PCM, 1, SL_SAMPLINGRATE_8,
        SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
        SL_SPEAKER_FRONT_CENTER, SL_BYTEORDER_LITTLEENDIAN};

    SLDataSource audioSrc = {&loc_bufq, &format_pcm};

    // configure audio sink
    SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, gOutputMixObject};
    SLDataSink audioSnk = {&loc_outmix, NULL};

    // create audio player
    const SLInterfaceID ids[3] = {SL_IID_BUFFERQUEUE, SL_IID_EFFECTSEND, SL_IID_VOLUME};
    const SLboolean req[3] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
    result = (*gEngineEngine)->CreateAudioPlayer(gEngineEngine, &gBQObject, &audioSrc, &audioSnk,
            3, ids, req);

    // realize the player
    result = (*gBQObject)->Realize(gBQObject, SL_BOOLEAN_FALSE);

    // get the play interface
    result = (*gBQObject)->GetInterface(gBQObject, SL_IID_PLAY, &gBQPlay);

    // get the buffer queue interface
    result = (*gBQObject)->GetInterface(gBQObject, SL_IID_BUFFERQUEUE,
            &gBQBufferQueue);

    // register callback on the buffer queue
    result = (*gBQBufferQueue)->RegisterCallback(gBQBufferQueue, bqPlayerCallback, NULL/*soundMix*/);

    // get the effect send interface
    result = (*gBQObject)->GetInterface(gBQObject, SL_IID_EFFECTSEND,
            &gBQEffectSend); 

    // set the player's state to playing
    result = (*gBQPlay)->SetPlayState(gBQPlay, SL_PLAYSTATE_PLAYING );
}
4

1 に答える 1

0

完全にはわかりませんが、エミュレータのOpenSLESサポートが実際には機能しないという点で正しいと思います。試したどのデバイスでも動作しますが、実際に動作させることはありません。

私のアプリケーションではAndroid2.2もサポートする必要があるため、JNIを使​​用してJavaAudioTrackAPIにアクセスするためのフォールバックがあります。エミュレーターが検出されたときに常にAudioTrackインターフェースを使用するように、アプリに特別なケースを追加しました。

于 2012-09-24T07:01:05.157 に答える