2012-12-21 52 views
0

我已将Android中的默认媒体框架从Stagefright更改为Gstreamer。这样做是为了使我们的项目变得灵活。Soundpool:示例未准备好

但是,当我运行一些apks时,应用程序启动时应用程序的所有声音都会播放,然后在Soundpool显示错误“sample#not READY”之后不播放。例如,在App Baby钢琴中,当我启动应用程序时,弹奏钢琴音节的声音,以及在进入播放模式后实际点击钢琴时,它不会播放。

我认为的问题是,当声音被加载到Soundpool中时,Gstreamer Mediaplayer对象被创建并且它被播放,并且在应用程序开始时它被完成。

在日志中显示Sample Channel Count(0)超出范围。它来自下面部分的SoundPoool.cpp文件。

status_t Sample::doLoad() { 
    uint32_t sampleRate; 
    int numChannels; 
    int format; 
    sp<IMemory> p; 
    LOGW("Start decode"); 
    if (mUrl) { 
     p = MediaPlayer::decode(mUrl, &sampleRate, &numChannels, &format); 
    } else { 
     p = MediaPlayer::decode(mFd, mOffset, mLength, &sampleRate, &numChannels, &format); 
     LOGW("close(%d)", mFd); 
     ::close(mFd); 
     mFd = -1; 
    } 
    if (p == 0) { 
     LOGE("Unable to load sample: %s", mUrl); 
     return -1; 
    } 
    LOGW("pointer = %p, size = %u, sampleRate = %u, numChannels = %d", 
      p->pointer(), p->size(), sampleRate, numChannels); 

    if (sampleRate > kMaxSampleRate) { 
     LOGE("Sample rate (%u) out of range", sampleRate); 
     return - 1; 
    } 

    if ((numChannels < 1) || (numChannels > 2)) { 
     LOGE("Sample channel count (%d) out of range", numChannels); 
     return - 1; 
    } 

    //_dumpBuffer(p->pointer(), p->size()); 
    uint8_t* q = static_cast<uint8_t*>(p->pointer()) + p->size() - 10; 
    //_dumpBuffer(q, 10, 10, false); 

    mData = p; 
    mSize = p->size(); 
    mSampleRate = sampleRate; 
    mNumChannels = numChannels; 
    mFormat = format; 
    mState = READY; 
    return 0; } 

和MediaPlayerService解码功能从代码段返回下面

sp<IMemory> MediaPlayerService::decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) 
{ 
    LOGD("decode(%d, %lld, %lld)", fd, offset, length); 
    sp<MemoryBase> mem; 
    sp<MediaPlayerBase> player; 

    player_type playerType = getPlayerType(fd, offset, length); 
    LOGD("player type = %d", playerType); 

    // create the right type of player 
    sp<AudioCache> cache = new AudioCache("decode_fd"); 
    player = android::createPlayer(playerType, cache.get(), cache->notify); 
    if (player == NULL) goto Exit; 
    if (player->hardwareOutput()) goto Exit; 

    static_cast<MediaPlayerInterface*>(player.get())->setAudioSink(cache); 

    // set data source 
    if (player->setDataSource(fd, offset, length) != NO_ERROR) goto Exit; 

    LOGD("prepare"); 
    player->prepareAsync(); 

    LOGD("wait for prepare"); 
    if (cache->wait() != NO_ERROR) goto Exit; 

    LOGD("start"); 
    player->start(); 

    LOGD("wait for playback complete"); 
    if (cache->wait() != NO_ERROR) goto Exit; 

    mem = new MemoryBase(cache->getHeap(), 0, cache->size()); 
    *pSampleRate = cache->sampleRate();//Nes 
    *pNumChannels = cache->channelCount(); 
    *pFormat = cache->format(); 

    LOGD("return memory @ %p, sampleRate=%u, channelCount = %d, format = %d", mem->pointer(), *pSampleRate, *pNumChannels, *pFormat); 

Exit: 
    if (player != 0) player->reset(); 
    ::close(fd); 
    return mem; 
} 

所有值作为无效的采样率,信道等具有值0得到从该函数返回。

样品时播放此之后,它显示错误“”样品#没有准备好”

int SoundPool::play(int sampleID, float leftVolume, float rightVolume, 
     int priority, int loop, float rate) 
{ 
    LOGW("sampleID=%d, leftVolume=%f, rightVolume=%f, priority=%d, loop=%d, rate=%f", 
      sampleID, leftVolume, rightVolume, priority, loop, rate); 
    sp<Sample> sample; 
    SoundChannel* channel; 
    int channelID; 

    // scope for lock 
    { 
     Mutex::Autolock lock(&mLock); 

     // is sample ready? 
     sample = findSample(sampleID); 
     if ((sample == 0) || (sample->state() != Sample::READY)) { 
      LOGW(" sample %d not READY", sampleID); 
      return 0; 
     } 

     dump(); 

     // allocate a channel 
     channel = allocateChannel(priority); 

     // no channel allocated - return 0 
     if (!channel) { 
      LOGW("No channel allocated"); 
      return 0; 
     } 

     channelID = ++mNextChannelID; 
    } 

    LOGW("channel state = %d", channel->state()); 
    channel->play(sample, channelID, leftVolume, rightVolume, priority, loop, rate); 
    return channelID; 
} 

是否有此problem..Plz帮助解决..

+0

发布日志和相关代码部分。 – Michael

+0

@Michael我稍微修改了这个问题,并添加了代码部分。 –

回答

0

样品不准备好通常表示它尚未加载,即它仍在加载(也许您切换到的框架可能会加载更长时间)。

您应该订阅其onLoadCompleteListener,并且当您收到回调,声音准备好了o被播放。在这之前,它不会被播放。

0

您可以使用此梅索德也

public void loadSound (String strSound, int stream) { 
    boolean loaded = false; 
    mSoundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() { 
      @Override 
      public void onLoadComplete(SoundPool soundPool, int sampleId, 
        int status) { 
       mSoundPool.play(stream, streamVolume, streamVolume, 1, LOOP_1_TIME, 1f); 
      } 
     }); 
    try { 
      stream= mSoundPool.load(aMan.openFd(strSound), 1); 
     } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 
0

我有同样的问题为Android 2.0,并使用.OGG格式,而不是用于当提到here我用的是声音的mp3格式解决。我希望这能解决你的问题。